@formatjs/cli-lib 8.5.1 → 8.5.3

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.
Files changed (58) hide show
  1. package/gts_extractor-Dc-C_f4R.js +14 -0
  2. package/gts_extractor-Dc-C_f4R.js.map +1 -0
  3. package/{src/hbs_extractor.js → hbs_extractor-Eiqkz4d7.js} +9 -8
  4. package/hbs_extractor-Eiqkz4d7.js.map +1 -0
  5. package/index.d.ts +144 -7
  6. package/index.js +633 -2
  7. package/index.js.map +1 -0
  8. package/package.json +4 -4
  9. package/parse_script-EspfGgzZ.js +93 -0
  10. package/parse_script-EspfGgzZ.js.map +1 -0
  11. package/{src/svelte_extractor.js → svelte_extractor-Fr1Z3JHX.js} +16 -37
  12. package/svelte_extractor-Fr1Z3JHX.js.map +1 -0
  13. package/vue_extractor-Btw05cfG.js +41 -0
  14. package/vue_extractor-Btw05cfG.js.map +1 -0
  15. package/main.d.ts +0 -1
  16. package/main.js +0 -3
  17. package/src/cli.d.ts +0 -2
  18. package/src/cli.js +0 -145
  19. package/src/compile.d.ts +0 -63
  20. package/src/compile.js +0 -95
  21. package/src/compile_folder.d.ts +0 -2
  22. package/src/compile_folder.js +0 -8
  23. package/src/console_utils.d.ts +0 -7
  24. package/src/console_utils.js +0 -62
  25. package/src/extract.d.ts +0 -87
  26. package/src/extract.js +0 -212
  27. package/src/formatters/crowdin.d.ts +0 -7
  28. package/src/formatters/crowdin.js +0 -21
  29. package/src/formatters/default.d.ts +0 -6
  30. package/src/formatters/default.js +0 -9
  31. package/src/formatters/index.d.ts +0 -9
  32. package/src/formatters/index.js +0 -31
  33. package/src/formatters/lokalise.d.ts +0 -9
  34. package/src/formatters/lokalise.js +0 -18
  35. package/src/formatters/simple.d.ts +0 -4
  36. package/src/formatters/simple.js +0 -8
  37. package/src/formatters/smartling.d.ts +0 -21
  38. package/src/formatters/smartling.js +0 -39
  39. package/src/formatters/transifex.d.ts +0 -9
  40. package/src/formatters/transifex.js +0 -18
  41. package/src/gts_extractor.d.ts +0 -1
  42. package/src/gts_extractor.js +0 -14
  43. package/src/hbs_extractor.d.ts +0 -1
  44. package/src/parse_script.d.ts +0 -7
  45. package/src/parse_script.js +0 -43
  46. package/src/pseudo_locale.d.ts +0 -22
  47. package/src/pseudo_locale.js +0 -231
  48. package/src/svelte_extractor.d.ts +0 -2
  49. package/src/verify/checkExtraKeys.d.ts +0 -1
  50. package/src/verify/checkExtraKeys.js +0 -32
  51. package/src/verify/checkMissingKeys.d.ts +0 -1
  52. package/src/verify/checkMissingKeys.js +0 -33
  53. package/src/verify/checkStructuralEquality.d.ts +0 -1
  54. package/src/verify/checkStructuralEquality.js +0 -71
  55. package/src/verify/index.d.ts +0 -13
  56. package/src/verify/index.js +0 -26
  57. package/src/vue_extractor.d.ts +0 -2
  58. package/src/vue_extractor.js +0 -58
package/index.js CHANGED
@@ -1,2 +1,633 @@
1
- export { default as extractAndWrite, extract } from "./src/extract.js";
2
- export { default as compileAndWrite, compile } from "./src/compile.js";
1
+ import { a as writeStdout, i as warn, n as debug, r as getStdinAsString, t as parseScript } from "./parse_script-EspfGgzZ.js";
2
+ import { interpolateName } from "@formatjs/ts-transformer";
3
+ import { outputFile } from "fs-extra/esm";
4
+ import * as stringifyNs from "json-stable-stringify";
5
+ import { resolve } from "path";
6
+ import { pathToFileURL } from "url";
7
+ import { readFile } from "fs/promises";
8
+ import { TYPE, isLiteralElement, isPluralElement, isSelectElement, isTagElement, parse } from "@formatjs/icu-messageformat-parser";
9
+ //#region \0rolldown/runtime.js
10
+ var __defProp = Object.defineProperty;
11
+ var __exportAll = (all, no_symbols) => {
12
+ let target = {};
13
+ for (var name in all) __defProp(target, name, {
14
+ get: all[name],
15
+ enumerable: true
16
+ });
17
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
18
+ return target;
19
+ };
20
+ //#endregion
21
+ //#region packages/cli-lib/formatters/crowdin.ts
22
+ var crowdin_exports = /* @__PURE__ */ __exportAll({
23
+ compile: () => compile$6,
24
+ format: () => format$5
25
+ });
26
+ const format$5 = (msgs) => {
27
+ const results = {};
28
+ for (const [id, msg] of Object.entries(msgs)) results[id] = {
29
+ message: msg.defaultMessage,
30
+ description: typeof msg.description === "string" ? msg.description : JSON.stringify(msg.description)
31
+ };
32
+ return results;
33
+ };
34
+ const compile$6 = (msgs) => {
35
+ const results = {};
36
+ for (const [id, msg] of Object.entries(msgs)) {
37
+ if (id === "smartling") continue;
38
+ results[id] = msg.message;
39
+ }
40
+ return results;
41
+ };
42
+ //#endregion
43
+ //#region packages/cli-lib/formatters/default.ts
44
+ var default_exports = /* @__PURE__ */ __exportAll({
45
+ compile: () => compile$5,
46
+ format: () => format$4
47
+ });
48
+ const format$4 = (msgs) => msgs;
49
+ const compile$5 = (msgs) => {
50
+ const results = {};
51
+ for (const k in msgs) results[k] = msgs[k].defaultMessage;
52
+ return results;
53
+ };
54
+ //#endregion
55
+ //#region packages/cli-lib/formatters/lokalise.ts
56
+ var lokalise_exports = /* @__PURE__ */ __exportAll({
57
+ compile: () => compile$4,
58
+ format: () => format$3
59
+ });
60
+ const format$3 = (msgs) => {
61
+ const results = {};
62
+ for (const [id, msg] of Object.entries(msgs)) results[id] = {
63
+ translation: msg.defaultMessage,
64
+ notes: typeof msg.description === "string" ? msg.description : JSON.stringify(msg.description)
65
+ };
66
+ return results;
67
+ };
68
+ const compile$4 = (msgs) => {
69
+ const results = {};
70
+ for (const [id, msg] of Object.entries(msgs)) results[id] = msg.translation;
71
+ return results;
72
+ };
73
+ //#endregion
74
+ //#region packages/cli-lib/formatters/simple.ts
75
+ var simple_exports = /* @__PURE__ */ __exportAll({
76
+ compile: () => compile$3,
77
+ format: () => format$2
78
+ });
79
+ const format$2 = (msgs) => {
80
+ return Object.keys(msgs).reduce((all, k) => {
81
+ all[k] = msgs[k].defaultMessage;
82
+ return all;
83
+ }, {});
84
+ };
85
+ const compile$3 = (msgs) => msgs;
86
+ //#endregion
87
+ //#region packages/cli-lib/formatters/smartling.ts
88
+ var smartling_exports = /* @__PURE__ */ __exportAll({
89
+ compareMessages: () => compareMessages,
90
+ compile: () => compile$2,
91
+ format: () => format$1
92
+ });
93
+ const format$1 = (msgs) => {
94
+ const results = { smartling: {
95
+ translate_paths: [{
96
+ path: "*/message",
97
+ key: "{*}/message",
98
+ instruction: "*/description"
99
+ }],
100
+ variants_enabled: true,
101
+ string_format: "icu"
102
+ } };
103
+ for (const [id, msg] of Object.entries(msgs)) results[id] = {
104
+ message: msg.defaultMessage,
105
+ description: typeof msg.description === "string" ? msg.description : JSON.stringify(msg.description)
106
+ };
107
+ return results;
108
+ };
109
+ const compareMessages = (el1, el2) => {
110
+ if (el1.key === "smartling") return -1;
111
+ if (el2.key === "smartling") return 1;
112
+ return el1.key < el2.key ? -1 : el1.key === el2.key ? 0 : 1;
113
+ };
114
+ const compile$2 = (msgs) => {
115
+ const results = {};
116
+ for (const [id, msg] of Object.entries(msgs)) {
117
+ if (id === "smartling") continue;
118
+ results[id] = msg.message;
119
+ }
120
+ return results;
121
+ };
122
+ //#endregion
123
+ //#region packages/cli-lib/formatters/transifex.ts
124
+ var transifex_exports = /* @__PURE__ */ __exportAll({
125
+ compile: () => compile$1,
126
+ format: () => format
127
+ });
128
+ const format = (msgs) => {
129
+ const results = {};
130
+ for (const [id, msg] of Object.entries(msgs)) results[id] = {
131
+ string: msg.defaultMessage,
132
+ developer_comment: typeof msg.description === "string" ? msg.description : JSON.stringify(msg.description)
133
+ };
134
+ return results;
135
+ };
136
+ const compile$1 = (msgs) => {
137
+ const results = {};
138
+ for (const [id, msg] of Object.entries(msgs)) results[id] = msg.string;
139
+ return results;
140
+ };
141
+ //#endregion
142
+ //#region packages/cli-lib/formatters/index.ts
143
+ async function resolveBuiltinFormatter(format) {
144
+ if (!format) return default_exports;
145
+ if (typeof format !== "string") return format;
146
+ switch (format) {
147
+ case "transifex": return transifex_exports;
148
+ case "smartling": return smartling_exports;
149
+ case "simple": return simple_exports;
150
+ case "lokalise": return lokalise_exports;
151
+ case "crowdin": return crowdin_exports;
152
+ }
153
+ try {
154
+ return import(pathToFileURL(resolve(process.cwd(), format)).href);
155
+ } catch (e) {
156
+ console.error(`Cannot resolve formatter ${format}`);
157
+ throw e;
158
+ }
159
+ }
160
+ //#endregion
161
+ //#region packages/cli-lib/extract.ts
162
+ const stringify$1 = stringifyNs.default || stringifyNs;
163
+ function calculateLineColFromOffset(text, start) {
164
+ if (!start) return {
165
+ line: 1,
166
+ col: 1
167
+ };
168
+ const lines = text.slice(0, start).split("\n");
169
+ const lastLine = lines[lines.length - 1];
170
+ return {
171
+ line: lines.length,
172
+ col: lastLine.length
173
+ };
174
+ }
175
+ async function processFile(source, fn, { idInterpolationPattern, ...opts }) {
176
+ let messages = [];
177
+ let meta;
178
+ const onMsgExtracted = opts.onMsgExtracted;
179
+ const onMetaExtracted = opts.onMetaExtracted;
180
+ opts = {
181
+ ...opts,
182
+ additionalComponentNames: ["$formatMessage", ...opts.additionalComponentNames || []],
183
+ onMsgExtracted(filePath, msgs) {
184
+ if (opts.extractSourceLocation) msgs = msgs.map((msg) => ({
185
+ ...msg,
186
+ ...calculateLineColFromOffset(source, msg.start)
187
+ }));
188
+ messages = messages.concat(msgs);
189
+ if (onMsgExtracted) onMsgExtracted(filePath, msgs);
190
+ },
191
+ onMetaExtracted(filePath, m) {
192
+ meta = m;
193
+ if (onMetaExtracted) onMetaExtracted(filePath, m);
194
+ }
195
+ };
196
+ if (!opts.overrideIdFn && idInterpolationPattern) opts = {
197
+ ...opts,
198
+ overrideIdFn: (id, defaultMessage, description, fileName) => id || interpolateName({ resourcePath: fileName }, idInterpolationPattern, { content: description ? `${defaultMessage}#${typeof description === "string" ? description : stringify$1(description)}` : defaultMessage })
199
+ };
200
+ debug("Processing opts for %s: %s", fn, opts);
201
+ const scriptParseFn = parseScript(opts, fn);
202
+ if (fn.endsWith(".vue")) {
203
+ debug("Processing %s using vue extractor", fn);
204
+ const { parseFile } = await import("./vue_extractor-Btw05cfG.js");
205
+ parseFile(source, fn, scriptParseFn);
206
+ } else if (fn.endsWith(".svelte")) {
207
+ debug("Processing %s using svelte extractor", fn);
208
+ const { parseFile } = await import("./svelte_extractor-Fr1Z3JHX.js");
209
+ parseFile(source, fn, scriptParseFn);
210
+ } else if (fn.endsWith(".hbs")) {
211
+ debug("Processing %s using hbs extractor", fn);
212
+ const { parseFile } = await import("./hbs_extractor-Eiqkz4d7.js");
213
+ parseFile(source, fn, opts);
214
+ } else if (fn.endsWith(".gts") || fn.endsWith(".gjs")) {
215
+ debug("Processing %s as gts/gjs file", fn);
216
+ const { parseFile } = await import("./gts_extractor-Dc-C_f4R.js");
217
+ parseFile(source, fn, opts);
218
+ } else {
219
+ debug("Processing %s using typescript extractor", fn);
220
+ scriptParseFn(source);
221
+ }
222
+ debug("Done extracting %s messages: %s", fn, messages);
223
+ if (meta) {
224
+ debug("Extracted meta:", meta);
225
+ messages.forEach((m) => m.meta = meta);
226
+ }
227
+ return {
228
+ messages,
229
+ meta
230
+ };
231
+ }
232
+ /**
233
+ * Extract strings from source files
234
+ * @param files list of files
235
+ * @param extractOpts extract options
236
+ * @returns messages serialized as JSON string since key order
237
+ * matters for some `format`
238
+ */
239
+ async function extract(files, extractOpts) {
240
+ const { throws, readFromStdin, signal, ...opts } = extractOpts;
241
+ const shouldThrow = throws === true;
242
+ const optsWithThrows = {
243
+ ...opts,
244
+ throws: shouldThrow,
245
+ onMsgError: !shouldThrow ? (_, e) => warn(e.message) : void 0
246
+ };
247
+ let rawResults = [];
248
+ try {
249
+ if (readFromStdin) {
250
+ debug(`Reading input from stdin`);
251
+ if (process.stdin.isTTY) warn("Reading source file from TTY.");
252
+ rawResults = [await processFile(await getStdinAsString(), "dummy", optsWithThrows)];
253
+ } else if (!shouldThrow) rawResults = (await Promise.allSettled(files.map(async (fn) => {
254
+ debug("Extracting file:", fn);
255
+ return processFile(await readFile(fn, {
256
+ encoding: "utf8",
257
+ signal
258
+ }), fn, optsWithThrows);
259
+ }))).map((result) => {
260
+ if (result.status === "fulfilled") return result.value;
261
+ else {
262
+ warn(String(result.reason));
263
+ return;
264
+ }
265
+ });
266
+ else rawResults = await Promise.all(files.map(async (fn) => {
267
+ debug("Extracting file:", fn);
268
+ return processFile(await readFile(fn, {
269
+ encoding: "utf8",
270
+ signal
271
+ }), fn, optsWithThrows);
272
+ }));
273
+ } catch (e) {
274
+ if (shouldThrow) throw e;
275
+ else warn(String(e));
276
+ }
277
+ const formatter = await resolveBuiltinFormatter(opts.format);
278
+ const extractionResults = rawResults.filter((r) => !!r);
279
+ const extractedMessages = /* @__PURE__ */ new Map();
280
+ for (const { messages } of extractionResults) for (const message of messages) {
281
+ const { id, description, defaultMessage } = message;
282
+ if (!id) {
283
+ const error = /* @__PURE__ */ new Error(`[FormatJS CLI] Missing message id for message:
284
+ ${JSON.stringify(message, void 0, 2)}`);
285
+ if (throws) throw error;
286
+ else warn(error.message);
287
+ continue;
288
+ }
289
+ if (extractedMessages.has(id)) {
290
+ const existing = extractedMessages.get(id);
291
+ if (stringify$1(description) !== stringify$1(existing.description) || defaultMessage !== existing.defaultMessage) {
292
+ const error = /* @__PURE__ */ new Error(`[FormatJS CLI] Duplicate message id: "${id}", but the \`description\` and/or \`defaultMessage\` are different.`);
293
+ if (throws) throw error;
294
+ else warn(error.message);
295
+ }
296
+ }
297
+ extractedMessages.set(id, message);
298
+ }
299
+ const results = {};
300
+ const messages = Array.from(extractedMessages.values());
301
+ for (const { id, ...msg } of messages) results[id] = msg;
302
+ if (typeof formatter.serialize === "function") return formatter.serialize(formatter.format(results));
303
+ return stringify$1(formatter.format(results), {
304
+ space: 2,
305
+ cmp: formatter.compareMessages || void 0
306
+ }) ?? "";
307
+ }
308
+ /**
309
+ * Extract strings from source files, also writes to a file.
310
+ * @param files list of files
311
+ * @param extractOpts extract options
312
+ * @returns A Promise that resolves if output file was written successfully
313
+ */
314
+ async function extractAndWrite(files, extractOpts) {
315
+ const { outFile, ...opts } = extractOpts;
316
+ const serializedResult = await extract(files, opts) + "\n";
317
+ if (outFile) {
318
+ debug("Writing output file:", outFile);
319
+ return outputFile(outFile, serializedResult);
320
+ }
321
+ await writeStdout(serializedResult);
322
+ }
323
+ //#endregion
324
+ //#region packages/cli-lib/pseudo_locale.ts
325
+ function forEachLiteralElement(ast, fn) {
326
+ ast.forEach((el) => {
327
+ if (isLiteralElement(el)) fn(el);
328
+ else if (isPluralElement(el) || isSelectElement(el)) for (const opt of Object.values(el.options)) forEachLiteralElement(opt.value, fn);
329
+ else if (isTagElement(el)) forEachLiteralElement(el.children, fn);
330
+ });
331
+ }
332
+ function generateXXLS(msg) {
333
+ const ast = typeof msg === "string" ? parse(msg) : msg;
334
+ const lastChunk = ast[ast.length - 1];
335
+ if (lastChunk && isLiteralElement(lastChunk)) {
336
+ lastChunk.value += "SSSSSSSSSSSSSSSSSSSSSSSSS";
337
+ return ast;
338
+ }
339
+ return [...ast, {
340
+ type: TYPE.literal,
341
+ value: "SSSSSSSSSSSSSSSSSSSSSSSSS"
342
+ }];
343
+ }
344
+ function generateXXAC(msg) {
345
+ const ast = typeof msg === "string" ? parse(msg) : msg;
346
+ forEachLiteralElement(ast, (el) => {
347
+ el.value = el.value.toUpperCase();
348
+ });
349
+ return ast;
350
+ }
351
+ function generateXXHA(msg) {
352
+ const ast = typeof msg === "string" ? parse(msg) : msg;
353
+ const [firstChunk, ...rest] = ast;
354
+ if (firstChunk && isLiteralElement(firstChunk)) {
355
+ firstChunk.value = "[javascript]" + firstChunk.value;
356
+ return [firstChunk, ...rest];
357
+ }
358
+ return [{
359
+ type: TYPE.literal,
360
+ value: "[javascript]"
361
+ }, ...ast];
362
+ }
363
+ const ACCENTED_MAP = {
364
+ "caps": [
365
+ 550,
366
+ 385,
367
+ 391,
368
+ 7698,
369
+ 7702,
370
+ 401,
371
+ 403,
372
+ 294,
373
+ 298,
374
+ 308,
375
+ 310,
376
+ 319,
377
+ 7742,
378
+ 544,
379
+ 510,
380
+ 420,
381
+ 586,
382
+ 344,
383
+ 350,
384
+ 358,
385
+ 364,
386
+ 7804,
387
+ 7814,
388
+ 7818,
389
+ 7822,
390
+ 7824
391
+ ],
392
+ "small": [
393
+ 551,
394
+ 384,
395
+ 392,
396
+ 7699,
397
+ 7703,
398
+ 402,
399
+ 608,
400
+ 295,
401
+ 299,
402
+ 309,
403
+ 311,
404
+ 320,
405
+ 7743,
406
+ 414,
407
+ 511,
408
+ 421,
409
+ 587,
410
+ 345,
411
+ 351,
412
+ 359,
413
+ 365,
414
+ 7805,
415
+ 7815,
416
+ 7819,
417
+ 7823,
418
+ 7825
419
+ ]
420
+ };
421
+ const FLIPPED_MAP = {
422
+ "caps": [
423
+ 8704,
424
+ 1296,
425
+ 8579,
426
+ 5601,
427
+ 398,
428
+ 8498,
429
+ 8513,
430
+ 72,
431
+ 73,
432
+ 383,
433
+ 1276,
434
+ 8514,
435
+ 87,
436
+ 78,
437
+ 79,
438
+ 1280,
439
+ 210,
440
+ 7450,
441
+ 83,
442
+ 8869,
443
+ 8745,
444
+ 581,
445
+ 77,
446
+ 88,
447
+ 8516,
448
+ 90
449
+ ],
450
+ "small": [
451
+ 592,
452
+ 113,
453
+ 596,
454
+ 112,
455
+ 477,
456
+ 607,
457
+ 387,
458
+ 613,
459
+ 305,
460
+ 638,
461
+ 670,
462
+ 645,
463
+ 623,
464
+ 117,
465
+ 111,
466
+ 100,
467
+ 98,
468
+ 633,
469
+ 115,
470
+ 647,
471
+ 110,
472
+ 652,
473
+ 653,
474
+ 120,
475
+ 654,
476
+ 122
477
+ ]
478
+ };
479
+ /**
480
+ * Based on: https://hg.mozilla.org/mozilla-central/file/a1f74e8c8fb72390d22054d6b00c28b1a32f6c43/intl/l10n/L10nRegistry.jsm#l425
481
+ */
482
+ function transformString(map, elongate = false, msg) {
483
+ return msg.replace(/[a-z]/gi, (ch) => {
484
+ const cc = ch.charCodeAt(0);
485
+ if (cc >= 97 && cc <= 122) {
486
+ const newChar = String.fromCodePoint(map.small[cc - 97]);
487
+ if (elongate && (cc === 97 || cc === 101 || cc === 111 || cc === 117)) return newChar + newChar;
488
+ return newChar;
489
+ }
490
+ if (cc >= 65 && cc <= 90) return String.fromCodePoint(map.caps[cc - 65]);
491
+ return ch;
492
+ });
493
+ }
494
+ /**
495
+ * accented - Ȧȧƈƈḗḗƞŧḗḗḓ Ḗḗƞɠŀīīşħ
496
+ * --------------------------------
497
+ *
498
+ * This locale replaces all Latin characters with their accented equivalents, and duplicates some
499
+ * vowels to create roughly 30% longer strings. Strings are wrapped in markers (square brackets),
500
+ * which help with detecting truncation.
501
+ */
502
+ function generateENXA(msg) {
503
+ const ast = typeof msg === "string" ? parse(msg) : msg;
504
+ forEachLiteralElement(ast, (el) => {
505
+ el.value = transformString(ACCENTED_MAP, true, el.value);
506
+ });
507
+ return [
508
+ {
509
+ type: TYPE.literal,
510
+ value: "["
511
+ },
512
+ ...ast,
513
+ {
514
+ type: TYPE.literal,
515
+ value: "]"
516
+ }
517
+ ];
518
+ }
519
+ /**
520
+ * bidi - ɥsıʅƃuƎ ıpıԐ
521
+ * -------------------
522
+ *
523
+ * This strategy replaces all Latin characters with their 180 degree rotated versions and enforces
524
+ * right to left text flow using Unicode UAX#9 Explicit Directional Embeddings. In this mode, the UI
525
+ * directionality will also be set to right-to-left.
526
+ */
527
+ function generateENXB(msg) {
528
+ const ast = typeof msg === "string" ? parse(msg) : msg;
529
+ forEachLiteralElement(ast, (el) => {
530
+ el.value = transformString(FLIPPED_MAP, false, el.value);
531
+ });
532
+ return [
533
+ {
534
+ type: TYPE.literal,
535
+ value: "‮"
536
+ },
537
+ ...ast,
538
+ {
539
+ type: TYPE.literal,
540
+ value: "‬"
541
+ }
542
+ ];
543
+ }
544
+ //#endregion
545
+ //#region packages/cli-lib/compile.ts
546
+ const stringify = stringifyNs.default || stringifyNs;
547
+ /**
548
+ * Aggregate `inputFiles` into a single JSON blob and compile.
549
+ * Also checks for conflicting IDs.
550
+ * Then returns the serialized result as a `string` since key order
551
+ * makes a difference in some vendor.
552
+ * @param inputFiles Input files
553
+ * @param opts Options
554
+ * @returns serialized result in string format
555
+ */
556
+ async function compile(inputFiles, opts = {}) {
557
+ debug("Compiling files:", inputFiles);
558
+ const { ast, format, pseudoLocale, skipErrors, ignoreTag, signal } = opts;
559
+ signal?.throwIfAborted();
560
+ const formatter = await resolveBuiltinFormatter(format);
561
+ const messages = {};
562
+ const messageAsts = {};
563
+ const idsWithFileName = {};
564
+ const compiledFiles = await Promise.all(inputFiles.map((f) => readFile(f, {
565
+ encoding: "utf8",
566
+ signal
567
+ }).then((content) => JSON.parse(content)).then(formatter.compile)));
568
+ debug("Compiled files:", compiledFiles);
569
+ for (let i = 0; i < inputFiles.length; i++) {
570
+ const inputFile = inputFiles[i];
571
+ debug("Processing file:", inputFile);
572
+ const compiled = compiledFiles[i];
573
+ for (const id in compiled) {
574
+ if (messages[id] && messages[id] !== compiled[id]) throw new Error(`Conflicting ID "${id}" with different translation found in these 2 files:
575
+ ID: ${id}
576
+ Message from ${idsWithFileName[id]}: ${messages[id]}
577
+ Message from ${inputFile}: ${compiled[id]}
578
+ `);
579
+ try {
580
+ const msgAst = parse(compiled[id], { ignoreTag });
581
+ messages[id] = compiled[id];
582
+ switch (pseudoLocale) {
583
+ case "xx-LS":
584
+ messageAsts[id] = generateXXLS(msgAst);
585
+ break;
586
+ case "xx-AC":
587
+ messageAsts[id] = generateXXAC(msgAst);
588
+ break;
589
+ case "xx-HA":
590
+ messageAsts[id] = generateXXHA(msgAst);
591
+ break;
592
+ case "en-XA":
593
+ messageAsts[id] = generateENXA(msgAst);
594
+ break;
595
+ case "en-XB":
596
+ messageAsts[id] = generateENXB(msgAst);
597
+ break;
598
+ default:
599
+ messageAsts[id] = msgAst;
600
+ break;
601
+ }
602
+ idsWithFileName[id] = inputFile;
603
+ } catch (e) {
604
+ warn("Error validating message \"%s\" with ID \"%s\" in file \"%s\"", compiled[id], id, inputFile);
605
+ if (!skipErrors) throw e;
606
+ }
607
+ }
608
+ }
609
+ return stringify(ast ? messageAsts : messages, {
610
+ space: 2,
611
+ cmp: formatter.compareMessages || void 0
612
+ }) ?? "";
613
+ }
614
+ /**
615
+ * Aggregate `inputFiles` into a single JSON blob and compile.
616
+ * Also checks for conflicting IDs and write output to `outFile`.
617
+ * @param inputFiles Input files
618
+ * @param compileOpts options
619
+ * @returns A `Promise` that resolves if file was written successfully
620
+ */
621
+ async function compileAndWrite(inputFiles, compileOpts = {}) {
622
+ const { outFile, ...opts } = compileOpts;
623
+ const serializedResult = await compile(inputFiles, opts) + "\n";
624
+ if (outFile) {
625
+ debug("Writing output file:", outFile);
626
+ return outputFile(outFile, serializedResult);
627
+ }
628
+ await writeStdout(serializedResult);
629
+ }
630
+ //#endregion
631
+ export { compile, compileAndWrite, extract, extractAndWrite };
632
+
633
+ //# sourceMappingURL=index.js.map