@let-value/translate-extract 1.0.9 → 1.0.10
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/bin/cli.cjs +2 -2
- package/dist/bin/cli.js +2 -2
- package/dist/bin/cli.js.map +1 -1
- package/dist/run-8jCGSKUe.cjs +184 -0
- package/dist/run-CMzN4vHt.js +150 -0
- package/dist/run-CMzN4vHt.js.map +1 -0
- package/dist/src/index.cjs +282 -120
- package/dist/src/index.d.cts +141 -62
- package/dist/src/index.d.cts.map +1 -1
- package/dist/src/index.d.ts +142 -63
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +281 -118
- package/dist/src/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/run-BMvkoNJ4.js +0 -192
- package/dist/run-BMvkoNJ4.js.map +0 -1
- package/dist/run-CbsVUbM3.cjs +0 -226
package/dist/src/index.cjs
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
const require_run = require('../run-
|
|
1
|
+
const require_run = require('../run-8jCGSKUe.cjs');
|
|
2
2
|
let node_path = require("node:path");
|
|
3
3
|
node_path = require_run.__toESM(node_path);
|
|
4
|
-
let glob = require("glob");
|
|
5
|
-
glob = require_run.__toESM(glob);
|
|
6
4
|
let node_fs_promises = require("node:fs/promises");
|
|
7
5
|
node_fs_promises = require_run.__toESM(node_fs_promises);
|
|
6
|
+
let gettext_parser = require("gettext-parser");
|
|
7
|
+
gettext_parser = require_run.__toESM(gettext_parser);
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
node_fs = require_run.__toESM(node_fs);
|
|
10
|
-
let radash = require("radash");
|
|
11
|
-
radash = require_run.__toESM(radash);
|
|
12
10
|
let tree_sitter = require("tree-sitter");
|
|
13
11
|
tree_sitter = require_run.__toESM(tree_sitter);
|
|
14
12
|
let tree_sitter_javascript = require("tree-sitter-javascript");
|
|
@@ -17,11 +15,53 @@ let tree_sitter_typescript = require("tree-sitter-typescript");
|
|
|
17
15
|
tree_sitter_typescript = require_run.__toESM(tree_sitter_typescript);
|
|
18
16
|
let oxc_resolver = require("oxc-resolver");
|
|
19
17
|
oxc_resolver = require_run.__toESM(oxc_resolver);
|
|
20
|
-
let gettext_parser = require("gettext-parser");
|
|
21
|
-
gettext_parser = require_run.__toESM(gettext_parser);
|
|
22
18
|
let plural_forms = require("plural-forms");
|
|
23
19
|
plural_forms = require_run.__toESM(plural_forms);
|
|
24
20
|
|
|
21
|
+
//#region src/plugins/cleanup/cleanup.ts
|
|
22
|
+
function cleanup() {
|
|
23
|
+
return {
|
|
24
|
+
name: "cleanup",
|
|
25
|
+
setup(build) {
|
|
26
|
+
build.context.logger?.debug("cleanup plugin initialized");
|
|
27
|
+
const processedDirs = /* @__PURE__ */ new Set();
|
|
28
|
+
const generated = /* @__PURE__ */ new Set();
|
|
29
|
+
build.onResolve({
|
|
30
|
+
namespace: "cleanup",
|
|
31
|
+
filter: /.*/
|
|
32
|
+
}, (args) => {
|
|
33
|
+
generated.add(args.path);
|
|
34
|
+
return args;
|
|
35
|
+
});
|
|
36
|
+
build.onProcess({
|
|
37
|
+
namespace: "cleanup",
|
|
38
|
+
filter: /.*/
|
|
39
|
+
}, async ({ path: path$1 }) => {
|
|
40
|
+
await build.defer("translate");
|
|
41
|
+
const dir = (0, node_path.dirname)(path$1);
|
|
42
|
+
if (processedDirs.has(dir)) return void 0;
|
|
43
|
+
processedDirs.add(dir);
|
|
44
|
+
const files = await node_fs_promises.default.readdir(dir).catch(() => []);
|
|
45
|
+
for (const f of files.filter((p) => p.endsWith(".po"))) {
|
|
46
|
+
const full = (0, node_path.join)(dir, f);
|
|
47
|
+
if (generated.has(full)) continue;
|
|
48
|
+
const contents = await node_fs_promises.default.readFile(full).catch(() => void 0);
|
|
49
|
+
if (!contents) continue;
|
|
50
|
+
const parsed = gettext_parser.po.parse(contents);
|
|
51
|
+
const hasTranslations = Object.entries(parsed.translations || {}).some(([ctx, msgs]) => Object.keys(msgs).some((id) => !(ctx === "" && id === "")));
|
|
52
|
+
if (hasTranslations) build.context.logger?.warn({ path: full }, "stray translation file");
|
|
53
|
+
else {
|
|
54
|
+
await node_fs_promises.default.unlink(full);
|
|
55
|
+
build.context.logger?.info({ path: full }, "removed empty translation file");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return void 0;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
25
65
|
//#region src/plugins/core/queries/comment.ts
|
|
26
66
|
function getReference(node, { path: path$1 }) {
|
|
27
67
|
const line = node.startPosition.row + 1;
|
|
@@ -401,7 +441,7 @@ const pluralQuery$1 = withComment({
|
|
|
401
441
|
|
|
402
442
|
//#endregion
|
|
403
443
|
//#region src/plugins/core/queries/index.ts
|
|
404
|
-
const queries = [
|
|
444
|
+
const queries$1 = [
|
|
405
445
|
messageQuery$1,
|
|
406
446
|
messageInvalidQuery,
|
|
407
447
|
gettextQuery,
|
|
@@ -424,28 +464,52 @@ function getLanguage(ext) {
|
|
|
424
464
|
default: return tree_sitter_javascript.default;
|
|
425
465
|
}
|
|
426
466
|
}
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
parser
|
|
433
|
-
language
|
|
434
|
-
|
|
435
|
-
|
|
467
|
+
const parserCache = /* @__PURE__ */ new Map();
|
|
468
|
+
const queryCache = /* @__PURE__ */ new WeakMap();
|
|
469
|
+
function getCachedParser(ext) {
|
|
470
|
+
let cached = parserCache.get(ext);
|
|
471
|
+
if (!cached) {
|
|
472
|
+
const parser = new tree_sitter.default();
|
|
473
|
+
const language = getLanguage(ext);
|
|
474
|
+
parser.setLanguage(language);
|
|
475
|
+
cached = {
|
|
476
|
+
parser,
|
|
477
|
+
language
|
|
478
|
+
};
|
|
479
|
+
parserCache.set(ext, cached);
|
|
480
|
+
}
|
|
481
|
+
return cached;
|
|
482
|
+
}
|
|
483
|
+
function getCachedQuery(language, pattern) {
|
|
484
|
+
let cache = queryCache.get(language);
|
|
485
|
+
if (!cache) {
|
|
486
|
+
cache = /* @__PURE__ */ new Map();
|
|
487
|
+
queryCache.set(language, cache);
|
|
488
|
+
}
|
|
489
|
+
let query = cache.get(pattern);
|
|
490
|
+
if (!query) {
|
|
491
|
+
query = new tree_sitter.default.Query(language, pattern);
|
|
492
|
+
cache.set(pattern, query);
|
|
493
|
+
}
|
|
494
|
+
return query;
|
|
495
|
+
}
|
|
436
496
|
function getParser(path$1) {
|
|
437
497
|
const ext = (0, node_path.extname)(path$1);
|
|
438
498
|
return getCachedParser(ext);
|
|
439
499
|
}
|
|
500
|
+
function getQuery(language, pattern) {
|
|
501
|
+
return getCachedQuery(language, pattern);
|
|
502
|
+
}
|
|
440
503
|
function parseSource$1(source, path$1) {
|
|
441
504
|
const context = { path: path$1 };
|
|
442
505
|
const { parser, language } = getParser(path$1);
|
|
443
506
|
const tree = parser.parse(source);
|
|
444
507
|
const translations = [];
|
|
508
|
+
const warnings = [];
|
|
445
509
|
const imports = [];
|
|
446
510
|
const seen = /* @__PURE__ */ new Set();
|
|
447
|
-
for (const spec of queries) {
|
|
448
|
-
const query =
|
|
511
|
+
for (const spec of queries$1) {
|
|
512
|
+
const query = getCachedQuery(language, spec.pattern);
|
|
449
513
|
for (const match of query.matches(tree.rootNode)) {
|
|
450
514
|
const message = spec.extract(match);
|
|
451
515
|
if (!message) continue;
|
|
@@ -460,17 +524,21 @@ function parseSource$1(source, path$1) {
|
|
|
460
524
|
reference
|
|
461
525
|
}
|
|
462
526
|
});
|
|
463
|
-
if (error)
|
|
527
|
+
if (error) warnings.push({
|
|
528
|
+
error,
|
|
529
|
+
reference
|
|
530
|
+
});
|
|
464
531
|
}
|
|
465
532
|
}
|
|
466
|
-
const importTreeQuery =
|
|
533
|
+
const importTreeQuery = getCachedQuery(language, importQuery.pattern);
|
|
467
534
|
for (const match of importTreeQuery.matches(tree.rootNode)) {
|
|
468
535
|
const imp = importQuery.extract(match);
|
|
469
536
|
if (imp) imports.push(imp);
|
|
470
537
|
}
|
|
471
538
|
return {
|
|
472
539
|
translations,
|
|
473
|
-
imports
|
|
540
|
+
imports,
|
|
541
|
+
warnings
|
|
474
542
|
};
|
|
475
543
|
}
|
|
476
544
|
|
|
@@ -527,39 +595,55 @@ function resolveImports(file, imports) {
|
|
|
527
595
|
//#endregion
|
|
528
596
|
//#region src/plugins/core/core.ts
|
|
529
597
|
const filter$1 = /\.([cm]?tsx?|jsx?)$/;
|
|
598
|
+
const namespace$1 = "source";
|
|
530
599
|
function core() {
|
|
531
600
|
return {
|
|
532
601
|
name: "core",
|
|
533
602
|
setup(build) {
|
|
534
603
|
build.context.logger?.debug("core plugin initialized");
|
|
535
|
-
build.onResolve({
|
|
604
|
+
build.onResolve({
|
|
605
|
+
filter: filter$1,
|
|
606
|
+
namespace: namespace$1
|
|
607
|
+
}, ({ entrypoint, path: path$1 }) => {
|
|
536
608
|
return {
|
|
537
609
|
entrypoint,
|
|
610
|
+
namespace: namespace$1,
|
|
538
611
|
path: (0, node_path.resolve)(path$1)
|
|
539
612
|
};
|
|
540
613
|
});
|
|
541
|
-
build.onLoad({
|
|
542
|
-
|
|
614
|
+
build.onLoad({
|
|
615
|
+
filter: filter$1,
|
|
616
|
+
namespace: namespace$1
|
|
617
|
+
}, async ({ entrypoint, path: path$1 }) => {
|
|
618
|
+
const data = await (0, node_fs_promises.readFile)(path$1, "utf8");
|
|
543
619
|
return {
|
|
544
620
|
entrypoint,
|
|
545
621
|
path: path$1,
|
|
546
|
-
|
|
622
|
+
namespace: namespace$1,
|
|
623
|
+
data
|
|
547
624
|
};
|
|
548
625
|
});
|
|
549
|
-
build.
|
|
550
|
-
|
|
626
|
+
build.onProcess({
|
|
627
|
+
filter: filter$1,
|
|
628
|
+
namespace: namespace$1
|
|
629
|
+
}, ({ entrypoint, path: path$1, data }) => {
|
|
630
|
+
const { translations, imports, warnings } = parseSource$1(data, path$1);
|
|
551
631
|
if (build.context.config.walk) {
|
|
552
632
|
const paths = resolveImports(path$1, imports);
|
|
553
|
-
for (const path$2 of paths) build.
|
|
633
|
+
for (const path$2 of paths) build.resolve({
|
|
554
634
|
entrypoint,
|
|
555
|
-
path: path$2
|
|
635
|
+
path: path$2,
|
|
636
|
+
namespace: namespace$1
|
|
556
637
|
});
|
|
557
638
|
}
|
|
558
|
-
|
|
639
|
+
for (const warning of warnings) build.context.logger?.warn(`${warning.error} at ${warning.reference}`);
|
|
640
|
+
build.resolve({
|
|
559
641
|
entrypoint,
|
|
560
642
|
path: path$1,
|
|
561
|
-
|
|
562
|
-
|
|
643
|
+
namespace: "translate",
|
|
644
|
+
data: translations
|
|
645
|
+
});
|
|
646
|
+
return void 0;
|
|
563
647
|
});
|
|
564
648
|
}
|
|
565
649
|
};
|
|
@@ -693,26 +777,74 @@ function merge(sources, existing, obsolete, locale, generatedAt) {
|
|
|
693
777
|
};
|
|
694
778
|
return gettext_parser.po.compile(poObj).toString();
|
|
695
779
|
}
|
|
780
|
+
const namespace = "translate";
|
|
696
781
|
function po() {
|
|
697
782
|
return {
|
|
698
783
|
name: "po",
|
|
699
784
|
setup(build) {
|
|
700
785
|
build.context.logger?.debug("po plugin initialized");
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
786
|
+
const collections = /* @__PURE__ */ new Map();
|
|
787
|
+
let dispatched = false;
|
|
788
|
+
build.onResolve({
|
|
789
|
+
filter: /.*/,
|
|
790
|
+
namespace
|
|
791
|
+
}, async ({ entrypoint, path: path$1, data }) => {
|
|
792
|
+
if (!data || !Array.isArray(data)) return void 0;
|
|
793
|
+
for (const locale of build.context.config.locales) {
|
|
794
|
+
const destination = build.context.config.destination({
|
|
795
|
+
entrypoint,
|
|
796
|
+
locale,
|
|
797
|
+
path: path$1
|
|
798
|
+
});
|
|
799
|
+
if (!collections.has(destination)) collections.set(destination, {
|
|
800
|
+
locale,
|
|
801
|
+
translations: []
|
|
802
|
+
});
|
|
803
|
+
collections.get(destination)?.translations.push(...data);
|
|
804
|
+
}
|
|
805
|
+
build.defer("source").then(() => {
|
|
806
|
+
if (dispatched) return;
|
|
807
|
+
dispatched = true;
|
|
808
|
+
for (const path$2 of collections.keys()) build.load({
|
|
809
|
+
entrypoint,
|
|
810
|
+
path: path$2,
|
|
811
|
+
namespace
|
|
812
|
+
});
|
|
813
|
+
});
|
|
814
|
+
return void 0;
|
|
815
|
+
});
|
|
816
|
+
build.onLoad({
|
|
817
|
+
filter: /.*\.po$/,
|
|
818
|
+
namespace
|
|
819
|
+
}, async ({ entrypoint, path: path$1 }) => {
|
|
820
|
+
const data = await node_fs_promises.default.readFile(path$1).catch(() => void 0);
|
|
704
821
|
return {
|
|
705
|
-
...rest,
|
|
706
822
|
entrypoint,
|
|
707
|
-
|
|
708
|
-
|
|
823
|
+
path: path$1,
|
|
824
|
+
namespace,
|
|
825
|
+
data
|
|
709
826
|
};
|
|
710
827
|
});
|
|
711
|
-
build.
|
|
712
|
-
|
|
713
|
-
|
|
828
|
+
build.onProcess({
|
|
829
|
+
filter: /.*\.po$/,
|
|
830
|
+
namespace
|
|
831
|
+
}, async ({ entrypoint, path: path$1, data }) => {
|
|
832
|
+
const collected = collections.get(path$1);
|
|
833
|
+
if (!collected) {
|
|
834
|
+
build.context.logger?.warn({ path: path$1 }, "no translations collected for this path");
|
|
835
|
+
return void 0;
|
|
836
|
+
}
|
|
837
|
+
const { locale, translations } = collected;
|
|
838
|
+
const record = collect(translations, locale);
|
|
839
|
+
const out = merge([{ translations: record }], data, build.context.config.obsolete, locale, build.context.generatedAt);
|
|
714
840
|
await node_fs_promises.default.mkdir((0, node_path.dirname)(path$1), { recursive: true });
|
|
715
841
|
await node_fs_promises.default.writeFile(path$1, out);
|
|
842
|
+
build.resolve({
|
|
843
|
+
entrypoint,
|
|
844
|
+
path: path$1,
|
|
845
|
+
namespace: "cleanup",
|
|
846
|
+
data: translations
|
|
847
|
+
});
|
|
716
848
|
});
|
|
717
849
|
}
|
|
718
850
|
};
|
|
@@ -722,7 +854,8 @@ function po() {
|
|
|
722
854
|
//#region src/configuration.ts
|
|
723
855
|
const defaultPlugins = {
|
|
724
856
|
core,
|
|
725
|
-
po
|
|
857
|
+
po,
|
|
858
|
+
cleanup
|
|
726
859
|
};
|
|
727
860
|
const defaultDestination = ({ entrypoint, locale }) => (0, node_path.join)((0, node_path.dirname)(entrypoint), "translations", `${(0, node_path.basename)(entrypoint, (0, node_path.extname)(entrypoint))}.${locale}.po`);
|
|
728
861
|
const defaultExclude = [
|
|
@@ -734,52 +867,40 @@ function normalizeExclude(exclude) {
|
|
|
734
867
|
if (!exclude) return [];
|
|
735
868
|
return Array.isArray(exclude) ? exclude : [exclude];
|
|
736
869
|
}
|
|
870
|
+
function resolveEntrypoint(ep) {
|
|
871
|
+
if (typeof ep === "string") return { entrypoint: ep };
|
|
872
|
+
const { entrypoint, destination, obsolete, exclude } = ep;
|
|
873
|
+
return {
|
|
874
|
+
entrypoint,
|
|
875
|
+
destination,
|
|
876
|
+
obsolete,
|
|
877
|
+
exclude: exclude ? normalizeExclude(exclude) : void 0
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
function resolvePlugins(user) {
|
|
881
|
+
if (typeof user === "function") return user(defaultPlugins);
|
|
882
|
+
if (Array.isArray(user)) return [...Object.values(defaultPlugins).map((plugin) => plugin()), ...user];
|
|
883
|
+
return Object.values(defaultPlugins).map((plugin) => plugin());
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Type helper to make it easier to use translate.config.ts
|
|
887
|
+
* @param config - {@link UserConfig}.
|
|
888
|
+
*/
|
|
737
889
|
function defineConfig(config) {
|
|
738
|
-
let plugins;
|
|
739
|
-
const user = config.plugins;
|
|
740
|
-
if (typeof user === "function") plugins = user(defaultPlugins);
|
|
741
|
-
else if (Array.isArray(user)) plugins = [...Object.values(defaultPlugins).map((plugin) => plugin()), ...user];
|
|
742
|
-
else plugins = Object.values(defaultPlugins).map((plugin) => plugin());
|
|
743
|
-
const raw = Array.isArray(config.entrypoints) ? config.entrypoints : [config.entrypoints];
|
|
744
|
-
const entrypoints = [];
|
|
745
|
-
for (const ep of raw) if (typeof ep === "string") {
|
|
746
|
-
const paths = (0, glob.globSync)(ep, { nodir: true });
|
|
747
|
-
if (paths.length === 0) entrypoints.push({ entrypoint: ep });
|
|
748
|
-
else for (const path$1 of paths) entrypoints.push({ entrypoint: path$1 });
|
|
749
|
-
} else {
|
|
750
|
-
const { entrypoint, destination: destination$1, obsolete: obsolete$1, exclude: exclude$1 } = ep;
|
|
751
|
-
const paths = (0, glob.globSync)(entrypoint, { nodir: true });
|
|
752
|
-
const epExclude = exclude$1 ? [...defaultExclude, ...normalizeExclude(exclude$1)] : void 0;
|
|
753
|
-
if (paths.length === 0) entrypoints.push({
|
|
754
|
-
entrypoint,
|
|
755
|
-
destination: destination$1,
|
|
756
|
-
obsolete: obsolete$1,
|
|
757
|
-
exclude: epExclude
|
|
758
|
-
});
|
|
759
|
-
else for (const path$1 of paths) entrypoints.push({
|
|
760
|
-
entrypoint: path$1,
|
|
761
|
-
destination: destination$1,
|
|
762
|
-
obsolete: obsolete$1,
|
|
763
|
-
exclude: epExclude
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
890
|
const defaultLocale = config.defaultLocale ?? "en";
|
|
767
|
-
const
|
|
768
|
-
const
|
|
769
|
-
const
|
|
770
|
-
const walk = config.walk ?? true;
|
|
771
|
-
const logLevel = config.logLevel ?? "info";
|
|
772
|
-
const exclude = [...defaultExclude, ...normalizeExclude(config.exclude)];
|
|
891
|
+
const plugins = resolvePlugins(config.plugins);
|
|
892
|
+
const raw = Array.isArray(config.entrypoints) ? config.entrypoints : [config.entrypoints];
|
|
893
|
+
const entrypoints = raw.map(resolveEntrypoint);
|
|
773
894
|
return {
|
|
774
895
|
plugins,
|
|
775
896
|
entrypoints,
|
|
776
897
|
defaultLocale,
|
|
777
|
-
locales,
|
|
778
|
-
destination,
|
|
779
|
-
obsolete,
|
|
780
|
-
walk,
|
|
781
|
-
logLevel,
|
|
782
|
-
exclude
|
|
898
|
+
locales: config.locales ?? [defaultLocale],
|
|
899
|
+
destination: config.destination ?? defaultDestination,
|
|
900
|
+
obsolete: config.obsolete ?? "mark",
|
|
901
|
+
walk: config.walk ?? true,
|
|
902
|
+
logLevel: config.logLevel ?? "info",
|
|
903
|
+
exclude: config.exclude ? normalizeExclude(config.exclude) : defaultExclude
|
|
783
904
|
};
|
|
784
905
|
}
|
|
785
906
|
|
|
@@ -798,12 +919,26 @@ function buildTemplate(node) {
|
|
|
798
919
|
if (text$1) strings[strings.length - 1] += text$1;
|
|
799
920
|
} else if (child.type === "jsx_expression") {
|
|
800
921
|
const expr = child.namedChildren[0];
|
|
801
|
-
if (!expr
|
|
922
|
+
if (!expr) return {
|
|
802
923
|
text: "",
|
|
803
|
-
error: "JSX
|
|
924
|
+
error: "Empty JSX expression"
|
|
925
|
+
};
|
|
926
|
+
if (expr.type === "identifier") {
|
|
927
|
+
values.push(expr.text);
|
|
928
|
+
strings.push("");
|
|
929
|
+
} else if (expr.type === "string") strings[strings.length - 1] += expr.text.slice(1, -1);
|
|
930
|
+
else if (expr.type === "template_string") {
|
|
931
|
+
const hasSubstitutions = expr.children.some((c) => c.type === "template_substitution");
|
|
932
|
+
if (hasSubstitutions) return {
|
|
933
|
+
text: "",
|
|
934
|
+
error: "JSX expressions with template substitutions are not supported"
|
|
935
|
+
};
|
|
936
|
+
const content = expr.text.slice(1, -1);
|
|
937
|
+
strings[strings.length - 1] += content;
|
|
938
|
+
} else return {
|
|
939
|
+
text: "",
|
|
940
|
+
error: "JSX expressions must be simple identifiers, strings, or template literals"
|
|
804
941
|
};
|
|
805
|
-
values.push(expr.text);
|
|
806
|
-
strings.push("");
|
|
807
942
|
} else if (child.type === "string") strings[strings.length - 1] += child.text.slice(1, -1);
|
|
808
943
|
else return {
|
|
809
944
|
text: "",
|
|
@@ -821,11 +956,24 @@ function buildAttrValue(node) {
|
|
|
821
956
|
if (node.type === "string") return { text: node.text.slice(1, -1) };
|
|
822
957
|
if (node.type === "jsx_expression") {
|
|
823
958
|
const expr = node.namedChildren[0];
|
|
824
|
-
if (!expr
|
|
959
|
+
if (!expr) return {
|
|
960
|
+
text: "",
|
|
961
|
+
error: "Empty JSX expression"
|
|
962
|
+
};
|
|
963
|
+
if (expr.type === "identifier") return { text: `\${${expr.text}}` };
|
|
964
|
+
else if (expr.type === "string") return { text: expr.text.slice(1, -1) };
|
|
965
|
+
else if (expr.type === "template_string") {
|
|
966
|
+
const hasSubstitutions = expr.children.some((c) => c.type === "template_substitution");
|
|
967
|
+
if (hasSubstitutions) return {
|
|
968
|
+
text: "",
|
|
969
|
+
error: "JSX expressions with template substitutions are not supported"
|
|
970
|
+
};
|
|
971
|
+
const content = expr.text.slice(1, -1);
|
|
972
|
+
return { text: content };
|
|
973
|
+
} else return {
|
|
825
974
|
text: "",
|
|
826
|
-
error: "JSX expressions must be simple identifiers"
|
|
975
|
+
error: "JSX expressions must be simple identifiers, strings, or template literals"
|
|
827
976
|
};
|
|
828
|
-
return { text: `\${${expr.text}}` };
|
|
829
977
|
}
|
|
830
978
|
return {
|
|
831
979
|
text: "",
|
|
@@ -838,9 +986,17 @@ function buildAttrValue(node) {
|
|
|
838
986
|
const messageQuery = withComment({
|
|
839
987
|
pattern: `(
|
|
840
988
|
[
|
|
841
|
-
(jsx_element (jsx_opening_element name: (identifier) @name))
|
|
842
|
-
(jsx_self_closing_element name: (identifier) @name)
|
|
843
|
-
|
|
989
|
+
(jsx_element (jsx_opening_element name: (identifier) @name)) @call
|
|
990
|
+
(jsx_self_closing_element name: (identifier) @name) @call
|
|
991
|
+
(lexical_declaration
|
|
992
|
+
(variable_declarator
|
|
993
|
+
value: [
|
|
994
|
+
(jsx_element (jsx_opening_element name: (identifier) @name)) @call
|
|
995
|
+
(jsx_self_closing_element name: (identifier) @name) @call
|
|
996
|
+
]
|
|
997
|
+
)
|
|
998
|
+
)
|
|
999
|
+
]
|
|
844
1000
|
(#eq? @name "Message")
|
|
845
1001
|
)`,
|
|
846
1002
|
extract(match) {
|
|
@@ -953,7 +1109,7 @@ const pluralQuery = withComment({
|
|
|
953
1109
|
|
|
954
1110
|
//#endregion
|
|
955
1111
|
//#region src/plugins/react/queries/index.ts
|
|
956
|
-
const queries
|
|
1112
|
+
const queries = [messageQuery, pluralQuery];
|
|
957
1113
|
|
|
958
1114
|
//#endregion
|
|
959
1115
|
//#region src/plugins/react/parse.ts
|
|
@@ -962,10 +1118,10 @@ function parseSource(source, path$1) {
|
|
|
962
1118
|
const { parser, language } = getParser(path$1);
|
|
963
1119
|
const tree = parser.parse(source);
|
|
964
1120
|
const translations = [];
|
|
965
|
-
const
|
|
1121
|
+
const warnings = [];
|
|
966
1122
|
const seen = /* @__PURE__ */ new Set();
|
|
967
|
-
for (const spec of
|
|
968
|
-
const query =
|
|
1123
|
+
for (const spec of queries) {
|
|
1124
|
+
const query = getQuery(language, spec.pattern);
|
|
969
1125
|
for (const match of query.matches(tree.rootNode)) {
|
|
970
1126
|
const message = spec.extract(match);
|
|
971
1127
|
if (!message) continue;
|
|
@@ -980,17 +1136,15 @@ function parseSource(source, path$1) {
|
|
|
980
1136
|
reference
|
|
981
1137
|
}
|
|
982
1138
|
});
|
|
983
|
-
if (error)
|
|
1139
|
+
if (error) warnings.push({
|
|
1140
|
+
error,
|
|
1141
|
+
reference
|
|
1142
|
+
});
|
|
984
1143
|
}
|
|
985
1144
|
}
|
|
986
|
-
const importTreeQuery = new tree_sitter.default.Query(language, importQuery.pattern);
|
|
987
|
-
for (const match of importTreeQuery.matches(tree.rootNode)) {
|
|
988
|
-
const imp = importQuery.extract(match);
|
|
989
|
-
if (imp) imports.push(imp);
|
|
990
|
-
}
|
|
991
1145
|
return {
|
|
992
1146
|
translations,
|
|
993
|
-
|
|
1147
|
+
warnings
|
|
994
1148
|
};
|
|
995
1149
|
}
|
|
996
1150
|
|
|
@@ -1002,40 +1156,48 @@ function react() {
|
|
|
1002
1156
|
name: "react",
|
|
1003
1157
|
setup(build) {
|
|
1004
1158
|
build.context.logger?.debug("react plugin initialized");
|
|
1005
|
-
build.onResolve({
|
|
1159
|
+
build.onResolve({
|
|
1160
|
+
filter: /.*/,
|
|
1161
|
+
namespace: "source"
|
|
1162
|
+
}, ({ entrypoint, path: path$1, namespace: namespace$2 }) => {
|
|
1006
1163
|
return {
|
|
1007
1164
|
entrypoint,
|
|
1165
|
+
namespace: namespace$2,
|
|
1008
1166
|
path: (0, node_path.resolve)(path$1)
|
|
1009
1167
|
};
|
|
1010
1168
|
});
|
|
1011
|
-
build.onLoad({
|
|
1012
|
-
|
|
1169
|
+
build.onLoad({
|
|
1170
|
+
filter,
|
|
1171
|
+
namespace: "source"
|
|
1172
|
+
}, async ({ entrypoint, path: path$1, namespace: namespace$2 }) => {
|
|
1173
|
+
const data = await (0, node_fs_promises.readFile)(path$1, "utf8");
|
|
1013
1174
|
return {
|
|
1014
1175
|
entrypoint,
|
|
1015
1176
|
path: path$1,
|
|
1016
|
-
|
|
1177
|
+
namespace: namespace$2,
|
|
1178
|
+
data
|
|
1017
1179
|
};
|
|
1018
1180
|
});
|
|
1019
|
-
build.
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
});
|
|
1027
|
-
}
|
|
1028
|
-
return {
|
|
1181
|
+
build.onProcess({
|
|
1182
|
+
filter,
|
|
1183
|
+
namespace: "source"
|
|
1184
|
+
}, ({ entrypoint, path: path$1, data }) => {
|
|
1185
|
+
const { translations, warnings } = parseSource(data, path$1);
|
|
1186
|
+
for (const warning of warnings) build.context.logger?.warn(`${warning.error} at ${warning.reference}`);
|
|
1187
|
+
build.resolve({
|
|
1029
1188
|
entrypoint,
|
|
1030
1189
|
path: path$1,
|
|
1031
|
-
|
|
1032
|
-
|
|
1190
|
+
namespace: "translate",
|
|
1191
|
+
data: translations
|
|
1192
|
+
});
|
|
1193
|
+
return void 0;
|
|
1033
1194
|
});
|
|
1034
1195
|
}
|
|
1035
1196
|
};
|
|
1036
1197
|
}
|
|
1037
1198
|
|
|
1038
1199
|
//#endregion
|
|
1200
|
+
exports.cleanup = cleanup;
|
|
1039
1201
|
exports.collect = collect;
|
|
1040
1202
|
exports.core = core;
|
|
1041
1203
|
exports.defineConfig = defineConfig;
|