@let-value/translate-extract 1.1.2 → 1.1.6-beta.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.
Files changed (49) hide show
  1. package/dist/bin/cli.cjs +40 -28
  2. package/dist/bin/{cli.js → cli.mjs} +39 -23
  3. package/dist/bin/cli.mjs.map +1 -0
  4. package/dist/{configuration-CTy0NMkD.d.cts → configuration-BVNh7M_I.d.cts} +33 -12
  5. package/dist/configuration-BVNh7M_I.d.cts.map +1 -0
  6. package/dist/{configuration-fs9HmV_j.d.ts → configuration-oHJyypq5.d.mts} +34 -12
  7. package/dist/configuration-oHJyypq5.d.mts.map +1 -0
  8. package/dist/exclude-CpTGSisK.mjs +21 -0
  9. package/dist/exclude-CpTGSisK.mjs.map +1 -0
  10. package/dist/exclude-CzNSDMG-.cjs +36 -0
  11. package/dist/{run-C8z_uhxb.js → run-Bv3fv1N8.mjs} +233 -206
  12. package/dist/run-Bv3fv1N8.mjs.map +1 -0
  13. package/dist/{run-DtE6y27D.cjs → run-oGs6tkeL.cjs} +297 -247
  14. package/dist/src/core.cjs +55 -4
  15. package/dist/src/core.d.cts +2 -3
  16. package/dist/src/core.d.mts +2 -0
  17. package/dist/{core-DR3oxhSq.js → src/core.mjs} +12 -15
  18. package/dist/src/core.mjs.map +1 -0
  19. package/dist/src/index.cjs +5 -6
  20. package/dist/src/index.d.cts +2 -4
  21. package/dist/src/index.d.cts.map +1 -1
  22. package/dist/src/index.d.mts +22 -0
  23. package/dist/src/index.d.mts.map +1 -0
  24. package/dist/src/index.mjs +3 -0
  25. package/dist/src/static.cjs +31 -6
  26. package/dist/src/static.d.cts +1 -1
  27. package/dist/src/static.d.mts +2 -0
  28. package/dist/{static-DQHT7uqP.js → src/static.mjs} +2 -2
  29. package/dist/src/static.mjs.map +1 -0
  30. package/package.json +62 -57
  31. package/dist/bin/cli.js.map +0 -1
  32. package/dist/chunk-CUT6urMc.cjs +0 -30
  33. package/dist/configuration-CTy0NMkD.d.cts.map +0 -1
  34. package/dist/configuration-fs9HmV_j.d.ts.map +0 -1
  35. package/dist/core-ACuLoi2B.d.ts +0 -1
  36. package/dist/core-CHb_Xdzl.cjs +0 -65
  37. package/dist/core-CPg6_re5.d.cts +0 -1
  38. package/dist/core-DR3oxhSq.js.map +0 -1
  39. package/dist/run-C8z_uhxb.js.map +0 -1
  40. package/dist/src/core.d.ts +0 -3
  41. package/dist/src/core.js +0 -4
  42. package/dist/src/index.d.ts +0 -24
  43. package/dist/src/index.d.ts.map +0 -1
  44. package/dist/src/index.js +0 -5
  45. package/dist/src/static.d.ts +0 -2
  46. package/dist/src/static.js +0 -3
  47. package/dist/static-CNiWpXhx.cjs +0 -52
  48. package/dist/static-DQHT7uqP.js.map +0 -1
  49. /package/dist/bin/{cli.d.ts → cli.d.mts} +0 -0
@@ -1,31 +1,16 @@
1
- import { isDeepStrictEqual } from "node:util";
1
+ import { r as isExcluded } from "./exclude-CpTGSisK.mjs";
2
+ import { builtinModules } from "node:module";
2
3
  import path, { dirname, extname, join, relative, resolve } from "node:path";
3
- import glob from "fast-glob";
4
4
  import fs, { readFile } from "node:fs/promises";
5
5
  import * as gettextParser from "gettext-parser";
6
- import fs$1 from "node:fs";
6
+ import fs$1, { realpathSync } from "node:fs";
7
7
  import Parser from "@keqingmoe/tree-sitter";
8
8
  import JavaScript from "tree-sitter-javascript";
9
9
  import TS from "tree-sitter-typescript";
10
10
  import { ResolverFactory } from "oxc-resolver";
11
11
  import { getFormula, getNPlurals } from "plural-forms";
12
-
13
- //#region src/defer.ts
14
- var Defer = class {
15
- pending = 0;
16
- promise = Promise.resolve();
17
- resolve;
18
- enqueue() {
19
- if (this.pending++ === 0) this.promise = new Promise((res) => {
20
- this.resolve = res;
21
- });
22
- }
23
- dequeue() {
24
- if (this.pending > 0 && --this.pending === 0) this.resolve?.();
25
- }
26
- };
27
-
28
- //#endregion
12
+ import { isDeepStrictEqual } from "node:util";
13
+ import glob from "fast-glob";
29
14
  //#region src/plugins/cleanup/cleanup.ts
30
15
  const namespace$2 = "cleanup";
31
16
  function cleanup() {
@@ -40,9 +25,9 @@ function cleanup() {
40
25
  build.onResolve({
41
26
  namespace: namespace$2,
42
27
  filter: /.*/
43
- }, ({ path: path$1 }) => {
44
- generated.add(path$1);
45
- dirs.add(dirname(path$1));
28
+ }, ({ path }) => {
29
+ generated.add(path);
30
+ dirs.add(dirname(path));
46
31
  Promise.all([
47
32
  build.defer("source"),
48
33
  build.defer("translate"),
@@ -50,9 +35,9 @@ function cleanup() {
50
35
  ]).then(() => {
51
36
  if (dispatched) return;
52
37
  dispatched = true;
53
- for (const path$2 of dirs.values()) build.process({
54
- entrypoint: path$2,
55
- path: path$2,
38
+ for (const path of dirs.values()) build.process({
39
+ entrypoint: path,
40
+ path,
56
41
  namespace: namespace$2,
57
42
  data: void 0
58
43
  });
@@ -61,12 +46,12 @@ function cleanup() {
61
46
  build.onProcess({
62
47
  namespace: namespace$2,
63
48
  filter: /.*/
64
- }, async ({ path: path$1 }) => {
65
- if (processed.has(path$1)) return;
66
- processed.add(path$1);
67
- const files = await fs.readdir(path$1).catch(() => []);
49
+ }, async ({ path }) => {
50
+ if (processed.has(path)) return;
51
+ processed.add(path);
52
+ const files = await fs.readdir(path).catch(() => []);
68
53
  for (const f of files.filter((p) => p.endsWith(".po"))) {
69
- const full = join(path$1, f);
54
+ const full = join(path, f);
70
55
  const contents = await fs.readFile(full).catch(() => void 0);
71
56
  if (!contents) continue;
72
57
  const parsed = gettextParser.po.parse(contents);
@@ -78,12 +63,11 @@ function cleanup() {
78
63
  }
79
64
  };
80
65
  }
81
-
82
66
  //#endregion
83
67
  //#region src/plugins/core/queries/comment.ts
84
- function getReference(node, { path: path$1 }) {
68
+ function getReference(node, { path }) {
85
69
  const line = node.startPosition.row + 1;
86
- return `${relative(process.cwd(), path$1).replace(/\\+/g, "/")}:${line}`;
70
+ return `${relative(process.cwd(), path).replace(/\\+/g, "/")}:${line}`;
87
71
  }
88
72
  function getComment(node) {
89
73
  const text = node.text;
@@ -108,7 +92,6 @@ const withComment = (query) => ({
108
92
  return result;
109
93
  }
110
94
  });
111
-
112
95
  //#endregion
113
96
  //#region src/plugins/core/queries/entrypoint.ts
114
97
  const entrypointCommentPattern = /(?:^|\s)@?translate-entrypoint(?:\s|$)/;
@@ -118,9 +101,20 @@ const entrypointQuery = {
118
101
  return match.captures.filter((capture) => capture.name === "comment").some((capture) => entrypointCommentPattern.test(getComment(capture.node)));
119
102
  }
120
103
  };
121
-
122
104
  //#endregion
123
105
  //#region src/plugins/core/queries/import.ts
106
+ function findImportParent(node) {
107
+ let current = node;
108
+ while (current) {
109
+ if (current.type === "import_statement" || current.type === "export_statement" || current.type === "call_expression") return current;
110
+ current = current.parent;
111
+ }
112
+ }
113
+ function isTypeOnly(parent) {
114
+ if (!parent) return false;
115
+ const text = parent.text.trimStart();
116
+ return /^import\s+type\b/.test(text) || /^export\s+type\b/.test(text) || /^export\s*{\s*type\b[^}]*}\s*from\b/.test(text);
117
+ }
124
118
  const importQuery = {
125
119
  pattern: `
126
120
  [
@@ -140,15 +134,21 @@ const importQuery = {
140
134
  (#eq? @obj "require")
141
135
  (#eq? @method "resolve"))
142
136
  (call_expression
143
- function: (import)
137
+ function: (import) @dynamic
144
138
  arguments: (arguments (string (string_fragment) @import)))
145
139
  ]
146
140
  `,
147
141
  extract(match) {
148
- return (match.captures.find((c) => c.name === "import")?.node)?.text;
142
+ const node = match.captures.find((c) => c.name === "import")?.node;
143
+ if (!node) return;
144
+ const parent = findImportParent(node);
145
+ return {
146
+ spec: node.text,
147
+ kind: match.captures.some((c) => c.name === "dynamic") ? "dynamic" : "static",
148
+ typeOnly: isTypeOnly(parent)
149
+ };
149
150
  }
150
151
  };
151
-
152
152
  //#endregion
153
153
  //#region src/plugins/core/queries/utils.ts
154
154
  const callPattern = (fnName, args, allowMember = true) => `(
@@ -169,7 +169,6 @@ function isDescendant(node, ancestor) {
169
169
  }
170
170
  return false;
171
171
  }
172
-
173
172
  //#endregion
174
173
  //#region src/plugins/core/queries/message.ts
175
174
  const notInPlural = (query) => ({
@@ -277,7 +276,6 @@ const messageInvalidQuery = notInPlural({
277
276
  };
278
277
  }
279
278
  });
280
-
281
279
  //#endregion
282
280
  //#region src/plugins/core/queries/plural-utils.ts
283
281
  const extractPluralForms = (name) => (match) => {
@@ -325,7 +323,6 @@ const extractPluralForms = (name) => (match) => {
325
323
  translation
326
324
  };
327
325
  };
328
-
329
326
  //#endregion
330
327
  //#region src/plugins/core/queries/context.ts
331
328
  const ctxCall = callPattern("context", `[
@@ -365,7 +362,6 @@ const contextMsgQuery = withComment({
365
362
  };
366
363
  }
367
364
  });
368
- const msgCall$3 = callPattern("message", messageArgs, false).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn");
369
365
  const contextPluralQuery = withComment({
370
366
  pattern: `(
371
367
  (call_expression
@@ -374,7 +370,7 @@ const contextPluralQuery = withComment({
374
370
  property: (property_identifier) @func
375
371
  )
376
372
  arguments: (arguments (
377
- (${msgCall$3} ("," )?)+
373
+ (${callPattern("message", messageArgs, false).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn")} ("," )?)+
378
374
  (number) @n
379
375
  ))
380
376
  ) @call
@@ -399,7 +395,6 @@ const contextInvalidQuery = withComment({
399
395
  };
400
396
  }
401
397
  });
402
-
403
398
  //#endregion
404
399
  //#region src/plugins/core/queries/gettext.ts
405
400
  const gettextQuery = withComment({
@@ -426,27 +421,20 @@ const gettextInvalidQuery = {
426
421
  };
427
422
  }
428
423
  };
429
-
430
424
  //#endregion
431
425
  //#region src/plugins/core/queries/ngettext.ts
432
- const msgCall$2 = callPattern("message", messageArgs).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn");
433
- const plainMsg$1 = `(${messageArg}) @msg`;
434
- const msgArg$1 = `[${msgCall$2} ${plainMsg$1}]`;
426
+ const msgArg$1 = `[${callPattern("message", messageArgs).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn")} ${`(${messageArg}) @msg`}]`;
435
427
  const ngettextQuery = withComment({
436
428
  pattern: callPattern("ngettext", `(arguments ${msgArg$1} "," ${msgArg$1} ("," ${msgArg$1})* "," (_) @n)`),
437
429
  extract: extractPluralForms("ngettext")
438
430
  });
439
-
440
431
  //#endregion
441
432
  //#region src/plugins/core/queries/npgettext.ts
442
- const msgCall$1 = callPattern("message", messageArgs).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn");
443
- const plainMsg = `(${messageArg}) @msg`;
444
- const msgArg = `[${msgCall$1} ${plainMsg}]`;
433
+ const msgArg = `[${callPattern("message", messageArgs).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn")} ${`(${messageArg}) @msg`}]`;
445
434
  const npgettextQuery = withComment({
446
435
  pattern: callPattern("npgettext", `(arguments (string (string_fragment) @msgctxt) "," ${msgArg} "," ${msgArg} ("," ${msgArg})* "," (_) @n)`),
447
436
  extract: extractPluralForms("npgettext")
448
437
  });
449
-
450
438
  //#endregion
451
439
  //#region src/plugins/core/queries/pgettext.ts
452
440
  const pgettextQuery = withComment({
@@ -464,18 +452,6 @@ const pgettextQuery = withComment({
464
452
  };
465
453
  }
466
454
  });
467
-
468
- //#endregion
469
- //#region src/plugins/core/queries/plural.ts
470
- const msgCall = callPattern("message", messageArgs, false).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn");
471
- const pluralQuery$1 = withComment({
472
- pattern: callPattern("plural", `(arguments (
473
- (${msgCall} ("," )?)+
474
- (number) @n
475
- ))`, false),
476
- extract: extractPluralForms("plural")
477
- });
478
-
479
455
  //#endregion
480
456
  //#region src/plugins/core/queries/index.ts
481
457
  const queries$1 = [
@@ -486,12 +462,17 @@ const queries$1 = [
486
462
  messageInvalidQuery,
487
463
  gettextQuery,
488
464
  gettextInvalidQuery,
489
- pluralQuery$1,
465
+ withComment({
466
+ pattern: callPattern("plural", `(arguments (
467
+ (${callPattern("message", messageArgs, false).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn")} ("," )?)+
468
+ (number) @n
469
+ ))`, false),
470
+ extract: extractPluralForms("plural")
471
+ }),
490
472
  ngettextQuery,
491
473
  pgettextQuery,
492
474
  npgettextQuery
493
475
  ];
494
-
495
476
  //#endregion
496
477
  //#region src/plugins/core/parse.ts
497
478
  function getLanguage(ext) {
@@ -530,16 +511,15 @@ function getCachedQuery(language, pattern) {
530
511
  }
531
512
  return query;
532
513
  }
533
- function getParser(path$1) {
534
- const ext = extname(path$1);
535
- return getCachedParser(ext);
514
+ function getParser(path) {
515
+ return getCachedParser(extname(path));
536
516
  }
537
517
  function getQuery(language, pattern) {
538
518
  return getCachedQuery(language, pattern);
539
519
  }
540
- function parseSource$1(source, path$1) {
541
- const context = { path: path$1 };
542
- const { parser, language } = getParser(path$1);
520
+ function parseSource$1(source, path) {
521
+ const context = { path };
522
+ const { parser, language } = getParser(path);
543
523
  const tree = parser.parse(source);
544
524
  const entrypoint = getCachedQuery(language, entrypointQuery.pattern).matches(tree.rootNode).some(entrypointQuery.extract);
545
525
  const translations = [];
@@ -580,7 +560,6 @@ function parseSource$1(source, path$1) {
580
560
  entrypoint
581
561
  };
582
562
  }
583
-
584
563
  //#endregion
585
564
  //#region src/plugins/core/resolve.ts
586
565
  function findTsconfig(dir) {
@@ -594,6 +573,12 @@ function findTsconfig(dir) {
594
573
  }
595
574
  }
596
575
  const resolverCache = /* @__PURE__ */ new Map();
576
+ const builtins = new Set([...builtinModules, ...builtinModules.map((name) => `node:${name}`)]);
577
+ function isBuiltin(spec) {
578
+ if (builtins.has(spec)) return true;
579
+ const [base, subpath] = (spec.startsWith("node:") ? spec.slice(5) : spec).split("/", 2);
580
+ return subpath !== void 0 && builtins.has(base);
581
+ }
597
582
  function getResolver(dir) {
598
583
  const tsconfig = findTsconfig(dir);
599
584
  const key = tsconfig ?? "__default__";
@@ -620,17 +605,48 @@ function getResolver(dir) {
620
605
  }
621
606
  return resolver;
622
607
  }
623
- function resolveImports(file, imports) {
608
+ function normalizeImportReference(imp) {
609
+ if (typeof imp === "string") return {
610
+ spec: imp,
611
+ kind: "static",
612
+ typeOnly: false
613
+ };
614
+ return imp;
615
+ }
616
+ function resolveImportResults(file, imports) {
624
617
  const dir = path.dirname(path.resolve(file));
625
618
  const resolver = getResolver(dir);
626
619
  const resolved = [];
627
- for (const spec of imports) {
628
- const res = resolver.sync(dir, spec);
629
- if (res.path) resolved.push(res.path);
620
+ const unresolved = [];
621
+ for (const imp of imports) {
622
+ const ref = normalizeImportReference(imp);
623
+ const { spec } = ref;
624
+ if (isBuiltin(spec)) continue;
625
+ try {
626
+ const res = resolver.sync(dir, spec);
627
+ if (res.path) resolved.push({
628
+ path: res.path,
629
+ import: {
630
+ ...ref,
631
+ spec: res.path
632
+ }
633
+ });
634
+ else unresolved.push({
635
+ spec,
636
+ error: res.error
637
+ });
638
+ } catch (error) {
639
+ unresolved.push({
640
+ spec,
641
+ error: error instanceof Error ? error.message : String(error)
642
+ });
643
+ }
630
644
  }
631
- return resolved;
645
+ return {
646
+ resolved,
647
+ unresolved
648
+ };
632
649
  }
633
-
634
650
  //#endregion
635
651
  //#region src/plugins/core/core.ts
636
652
  const filter$1 = /\.([cm]?tsx?|jsx?)$/;
@@ -643,55 +659,67 @@ function core() {
643
659
  build.onResolve({
644
660
  filter: filter$1,
645
661
  namespace: namespace$1
646
- }, ({ entrypoint, path: path$1 }) => {
662
+ }, ({ entrypoint, path, import: imp, data }) => {
647
663
  return {
648
664
  entrypoint,
649
665
  namespace: namespace$1,
650
- path: resolve(path$1)
666
+ path: resolve(path),
667
+ import: imp,
668
+ data
651
669
  };
652
670
  });
653
671
  build.onLoad({
654
672
  filter: filter$1,
655
673
  namespace: namespace$1
656
- }, async ({ entrypoint, path: path$1 }) => {
657
- const data = await readFile(path$1, "utf8");
674
+ }, async ({ entrypoint, path }) => {
658
675
  return {
659
676
  entrypoint,
660
- path: path$1,
677
+ path,
661
678
  namespace: namespace$1,
662
- data
679
+ data: await readFile(path, "utf8")
663
680
  };
664
681
  });
665
682
  build.onProcess({
666
683
  filter: filter$1,
667
684
  namespace: namespace$1
668
- }, ({ entrypoint, path: path$1, data }) => {
669
- const result = parseSource$1(data, path$1);
670
- if (result.entrypoint && entrypoint !== path$1) {
671
- build.source(path$1);
685
+ }, ({ entrypoint, path, data }) => {
686
+ const result = parseSource$1(data, path);
687
+ if (result.entrypoint && entrypoint !== path) {
688
+ build.source(path);
672
689
  return {
673
690
  entrypoint,
674
- path: path$1,
691
+ path,
675
692
  namespace: namespace$1,
676
693
  data: []
677
694
  };
678
695
  }
679
696
  const { translations, imports, warnings } = result;
680
697
  if (build.context.config.walk) {
681
- const paths = resolveImports(path$1, imports);
682
- for (const path$2 of paths) {
683
- if (build.context.paths.has(path$2)) continue;
698
+ const { resolved, unresolved } = resolveImportResults(path, imports);
699
+ for (const result of resolved) {
700
+ if (build.context.paths.has(result.path)) continue;
684
701
  build.resolve({
685
702
  entrypoint,
686
- path: path$2,
687
- namespace: namespace$1
703
+ path: result.path,
704
+ namespace: namespace$1,
705
+ import: result.import
688
706
  });
689
707
  }
708
+ for (const { spec, error } of unresolved) {
709
+ const imp = imports.find((imp) => imp.spec === spec);
710
+ if (imp && isExcluded({
711
+ entrypoint,
712
+ path: spec,
713
+ namespace: namespace$1,
714
+ import: imp
715
+ }, build.context.config.exclude)) continue;
716
+ build.context.logger?.warn(`Unable to resolve import "${spec}" from ${path}${error ? `: ${error}` : ""}`);
717
+ }
690
718
  }
691
719
  for (const warning of warnings) build.context.logger?.warn(`${warning.error} at ${warning.reference}`);
692
720
  build.resolve({
693
721
  entrypoint,
694
- path: path$1,
722
+ path,
695
723
  namespace: "translate",
696
724
  data: translations
697
725
  });
@@ -699,7 +727,6 @@ function core() {
699
727
  }
700
728
  };
701
729
  }
702
-
703
730
  //#endregion
704
731
  //#region src/plugins/po/collect.ts
705
732
  function collect(source, locale) {
@@ -734,7 +761,6 @@ function collect(source, locale) {
734
761
  }
735
762
  return translations;
736
763
  }
737
-
738
764
  //#endregion
739
765
  //#region src/plugins/po/hasChanges.ts
740
766
  const IGNORED_HEADER_KEYS = new Set(["pot-creation-date", "po-revision-date"]);
@@ -748,9 +774,7 @@ function normalizeHeaderString(value) {
748
774
  }).map((line) => {
749
775
  const separatorIndex = line.indexOf(":");
750
776
  if (separatorIndex === -1) return line;
751
- const key = line.slice(0, separatorIndex).trim().toLowerCase();
752
- const value$1 = line.slice(separatorIndex + 1);
753
- return `${key}:${value$1}`;
777
+ return `${line.slice(0, separatorIndex).trim().toLowerCase()}:${line.slice(separatorIndex + 1)}`;
754
778
  });
755
779
  if (hadTrailingNewline && filtered[filtered.length - 1] !== "") filtered.push("");
756
780
  return filtered.join("\n");
@@ -769,11 +793,8 @@ function normalize(translations) {
769
793
  }
770
794
  function hasChanges(left, right) {
771
795
  if (!right) return true;
772
- const normalizedLeft = normalize(left);
773
- const normalizedRight = normalize(right);
774
- return !isDeepStrictEqual(normalizedLeft, normalizedRight);
796
+ return !isDeepStrictEqual(normalize(left), normalize(right));
775
797
  }
776
-
777
798
  //#endregion
778
799
  //#region src/plugins/po/merge.ts
779
800
  function formatDate(date) {
@@ -784,10 +805,7 @@ function formatDate(date) {
784
805
  const hours = pad(date.getHours());
785
806
  const minutes = pad(date.getMinutes());
786
807
  const tzo = -date.getTimezoneOffset();
787
- const sign = tzo >= 0 ? "+" : "-";
788
- const offsetHours = pad(Math.floor(Math.abs(tzo) / 60));
789
- const offsetMinutes = pad(Math.abs(tzo) % 60);
790
- return `${year}-${month}-${day} ${hours}:${minutes}${sign}${offsetHours}${offsetMinutes}`;
808
+ return `${year}-${month}-${day} ${hours}:${minutes}${tzo >= 0 ? "+" : "-"}${pad(Math.floor(Math.abs(tzo) / 60))}${pad(Math.abs(tzo) % 60)}`;
791
809
  }
792
810
  function merge(sources, existing, obsolete, locale, generatedAt) {
793
811
  let headers = {};
@@ -804,22 +822,22 @@ function merge(sources, existing, obsolete, locale, generatedAt) {
804
822
  }
805
823
  }
806
824
  const collected = { "": {} };
807
- for (const { translations: translations$1 } of sources) for (const [ctx, msgs] of Object.entries(translations$1)) {
825
+ for (const { translations } of sources) for (const [ctx, msgs] of Object.entries(translations)) {
808
826
  if (!collected[ctx]) collected[ctx] = {};
809
827
  for (const [id, entry] of Object.entries(msgs)) {
810
- const existing$1 = collected[ctx][id];
828
+ const existing = collected[ctx][id];
811
829
  const refs = /* @__PURE__ */ new Set();
812
- if (existing$1?.comments?.reference) existing$1.comments.reference.split(/\r?\n|\r/).forEach((r) => {
830
+ if (existing?.comments?.reference) existing.comments.reference.split(/\r?\n|\r/).forEach((r) => {
813
831
  refs.add(r);
814
832
  });
815
833
  if (entry.comments?.reference) entry.comments.reference.split(/\r?\n|\r/).forEach((r) => {
816
834
  refs.add(r);
817
835
  });
818
836
  collected[ctx][id] = {
819
- ...existing$1,
837
+ ...existing,
820
838
  ...entry,
821
839
  comments: {
822
- ...existing$1?.comments,
840
+ ...existing?.comments,
823
841
  ...entry.comments,
824
842
  reference: refs.size ? Array.from(refs).join("\n") : void 0
825
843
  }
@@ -870,7 +888,6 @@ function merge(sources, existing, obsolete, locale, generatedAt) {
870
888
  ...obsolete === "mark" && Object.keys(obsoleteTranslations).length ? { obsolete: obsoleteTranslations } : {}
871
889
  };
872
890
  }
873
-
874
891
  //#endregion
875
892
  //#region src/plugins/po/po.ts
876
893
  const namespace = "translate";
@@ -884,13 +901,13 @@ function po() {
884
901
  build.onResolve({
885
902
  filter: /.*/,
886
903
  namespace
887
- }, async ({ entrypoint, path: path$1, data }) => {
904
+ }, async ({ entrypoint, path, data }) => {
888
905
  if (!data || !Array.isArray(data)) return;
889
906
  for (const locale of build.context.config.locales) {
890
907
  const destination = build.context.config.destination({
891
908
  entrypoint,
892
909
  locale,
893
- path: path$1
910
+ path
894
911
  });
895
912
  if (!collections.has(destination)) collections.set(destination, {
896
913
  locale,
@@ -901,9 +918,9 @@ function po() {
901
918
  Promise.all([build.defer("source"), build.defer(namespace)]).then(() => {
902
919
  if (dispatched) return;
903
920
  dispatched = true;
904
- for (const path$2 of collections.keys()) build.load({
921
+ for (const path of collections.keys()) build.load({
905
922
  entrypoint,
906
- path: path$2,
923
+ path,
907
924
  namespace
908
925
  });
909
926
  });
@@ -911,35 +928,33 @@ function po() {
911
928
  build.onLoad({
912
929
  filter: /.*\.po$/,
913
930
  namespace
914
- }, async ({ entrypoint, path: path$1 }) => {
915
- const contents = await fs.readFile(path$1).catch(() => void 0);
916
- const data = contents ? gettextParser.po.parse(contents) : void 0;
931
+ }, async ({ entrypoint, path }) => {
932
+ const contents = await fs.readFile(path).catch(() => void 0);
917
933
  return {
918
934
  entrypoint,
919
- path: path$1,
935
+ path,
920
936
  namespace,
921
- data
937
+ data: contents ? gettextParser.po.parse(contents) : void 0
922
938
  };
923
939
  });
924
940
  build.onProcess({
925
941
  filter: /.*\.po$/,
926
942
  namespace
927
- }, async ({ entrypoint, path: path$1, data }) => {
928
- const collected = collections.get(path$1);
943
+ }, async ({ entrypoint, path, data }) => {
944
+ const collected = collections.get(path);
929
945
  if (!collected) {
930
- build.context.logger?.warn({ path: path$1 }, "no translations collected for this path");
946
+ build.context.logger?.warn({ path }, "no translations collected for this path");
931
947
  return;
932
948
  }
933
949
  const { locale, translations } = collected;
934
- const record = collect(translations, locale);
935
- const out = merge([{ translations: record }], data, build.context.config.obsolete, locale, build.context.generatedAt);
950
+ const out = merge([{ translations: collect(translations, locale) }], data, build.context.config.obsolete, locale, build.context.generatedAt);
936
951
  if (hasChanges(out, data)) {
937
- await fs.mkdir(dirname(path$1), { recursive: true });
938
- await fs.writeFile(path$1, gettextParser.po.compile(out));
952
+ await fs.mkdir(dirname(path), { recursive: true });
953
+ await fs.writeFile(path, gettextParser.po.compile(out));
939
954
  }
940
955
  build.resolve({
941
956
  entrypoint,
942
- path: path$1,
957
+ path,
943
958
  namespace: "cleanup",
944
959
  data: translations
945
960
  });
@@ -947,7 +962,6 @@ function po() {
947
962
  }
948
963
  };
949
964
  }
950
-
951
965
  //#endregion
952
966
  //#region src/plugins/react/queries/utils.ts
953
967
  function buildTemplate(node) {
@@ -963,10 +977,10 @@ function buildTemplate(node) {
963
977
  segmentStart = Math.max(segmentStart, endIndex);
964
978
  return;
965
979
  }
966
- const text$1 = source.slice(segmentStart, endIndex);
967
- if (text$1) parts.push({
980
+ const text = source.slice(segmentStart, endIndex);
981
+ if (text) parts.push({
968
982
  kind: "text",
969
- text: text$1,
983
+ text,
970
984
  raw: true
971
985
  });
972
986
  segmentStart = endIndex;
@@ -1074,7 +1088,6 @@ function buildAttrValue(node) {
1074
1088
  error: "Unsupported JSX child"
1075
1089
  };
1076
1090
  }
1077
-
1078
1091
  //#endregion
1079
1092
  //#region src/plugins/react/queries/message.ts
1080
1093
  const messageQuery = withComment({
@@ -1130,7 +1143,6 @@ const messageQuery = withComment({
1130
1143
  };
1131
1144
  }
1132
1145
  });
1133
-
1134
1146
  //#endregion
1135
1147
  //#region src/plugins/react/queries/plural.ts
1136
1148
  function parseForms(node) {
@@ -1156,7 +1168,9 @@ function parseForms(node) {
1156
1168
  }
1157
1169
  return { forms };
1158
1170
  }
1159
- const pluralQuery = withComment({
1171
+ //#endregion
1172
+ //#region src/plugins/react/queries/index.ts
1173
+ const queries = [messageQuery, withComment({
1160
1174
  pattern: `(
1161
1175
  [
1162
1176
  (jsx_element (jsx_opening_element name: (identifier) @name))
@@ -1199,17 +1213,12 @@ const pluralQuery = withComment({
1199
1213
  translation
1200
1214
  };
1201
1215
  }
1202
- });
1203
-
1204
- //#endregion
1205
- //#region src/plugins/react/queries/index.ts
1206
- const queries = [messageQuery, pluralQuery];
1207
-
1216
+ })];
1208
1217
  //#endregion
1209
1218
  //#region src/plugins/react/parse.ts
1210
- function parseSource(source, path$1) {
1211
- const context = { path: path$1 };
1212
- const { parser, language } = getParser(path$1);
1219
+ function parseSource(source, path) {
1220
+ const context = { path };
1221
+ const { parser, language } = getParser(path);
1213
1222
  const tree = parser.parse(source);
1214
1223
  const translations = [];
1215
1224
  const warnings = [];
@@ -1241,7 +1250,6 @@ function parseSource(source, path$1) {
1241
1250
  warnings
1242
1251
  };
1243
1252
  }
1244
-
1245
1253
  //#endregion
1246
1254
  //#region src/plugins/react/react.ts
1247
1255
  const filter = /\.[cm]?[jt]sx$/;
@@ -1253,12 +1261,12 @@ function react() {
1253
1261
  build.onProcess({
1254
1262
  filter,
1255
1263
  namespace: "source"
1256
- }, ({ entrypoint, path: path$1, data }) => {
1257
- const { translations, warnings } = parseSource(data, path$1);
1264
+ }, ({ entrypoint, path, data }) => {
1265
+ const { translations, warnings } = parseSource(data, path);
1258
1266
  for (const warning of warnings) build.context.logger?.warn(`${warning.error} at ${warning.reference}`);
1259
1267
  build.resolve({
1260
1268
  entrypoint,
1261
- path: path$1,
1269
+ path,
1262
1270
  namespace: "translate",
1263
1271
  data: translations
1264
1272
  });
@@ -1266,7 +1274,21 @@ function react() {
1266
1274
  }
1267
1275
  };
1268
1276
  }
1269
-
1277
+ //#endregion
1278
+ //#region src/defer.ts
1279
+ var Defer = class {
1280
+ pending = 0;
1281
+ promise = Promise.resolve();
1282
+ resolve;
1283
+ enqueue() {
1284
+ if (this.pending++ === 0) this.promise = new Promise((res) => {
1285
+ this.resolve = res;
1286
+ });
1287
+ }
1288
+ dequeue() {
1289
+ if (this.pending > 0 && --this.pending === 0) this.resolve?.();
1290
+ }
1291
+ };
1270
1292
  //#endregion
1271
1293
  //#region src/plugins/static.ts
1272
1294
  const original = {
@@ -1279,13 +1301,12 @@ function resolveStaticPlugin(item) {
1279
1301
  if ("static" in item) return original[item.static.name](...item.static.props);
1280
1302
  return item;
1281
1303
  }
1282
-
1283
1304
  //#endregion
1284
1305
  //#region src/run.ts
1285
1306
  async function getPaths(entrypoint) {
1286
1307
  const pattern = entrypoint.entrypoint.replace(/\\/g, "/");
1287
1308
  const paths = glob.isDynamicPattern(pattern) ? await glob(pattern, { onlyFiles: true }) : [entrypoint.entrypoint];
1288
- return new Set(paths.map((path$1) => resolve(path$1)));
1309
+ return new Set(paths.map((path) => resolve(path)));
1289
1310
  }
1290
1311
  async function run(entrypoint, { config, logger }) {
1291
1312
  const destination = entrypoint.destination ?? config.destination;
@@ -1317,19 +1338,25 @@ async function run(entrypoint, { config, logger }) {
1317
1338
  };
1318
1339
  const pending = /* @__PURE__ */ new Map();
1319
1340
  const queue = [];
1320
- function getDeferred(namespace$3) {
1321
- let defer$1 = pending.get(namespace$3);
1322
- if (defer$1 === void 0) {
1323
- defer$1 = new Defer();
1324
- pending.set(namespace$3, defer$1);
1341
+ function getDeferred(namespace) {
1342
+ let defer = pending.get(namespace);
1343
+ if (defer === void 0) {
1344
+ defer = new Defer();
1345
+ pending.set(namespace, defer);
1325
1346
  }
1326
- return defer$1;
1347
+ return defer;
1327
1348
  }
1328
- function defer(namespace$3) {
1329
- return getDeferred(namespace$3).promise;
1349
+ function defer(namespace) {
1350
+ return getDeferred(namespace).promise;
1330
1351
  }
1331
- function source(path$1) {
1332
- const resolvedPath = resolve(path$1);
1352
+ function source(path) {
1353
+ const abs = resolve(path);
1354
+ let resolvedPath;
1355
+ try {
1356
+ resolvedPath = realpathSync(abs);
1357
+ } catch {
1358
+ resolvedPath = abs;
1359
+ }
1333
1360
  if (paths.has(resolvedPath)) return;
1334
1361
  logger?.debug({
1335
1362
  entrypoint: entrypoint.entrypoint,
@@ -1343,74 +1370,74 @@ async function run(entrypoint, { config, logger }) {
1343
1370
  });
1344
1371
  }
1345
1372
  function resolve$1(args) {
1346
- const { entrypoint: entrypoint$1, path: path$1, namespace: namespace$3 } = args;
1347
- const key = `${entrypoint$1}:${namespace$3}:${path$1}`;
1373
+ const { entrypoint, path, namespace } = args;
1374
+ const key = `${entrypoint}:${namespace}:${path}`;
1348
1375
  const visited = resolved.has(key);
1349
- const skipped = context.config.exclude.some((ex) => typeof ex === "function" ? ex(args) : ex.test(args.path));
1376
+ const skipped = isExcluded(args, context.config.exclude);
1350
1377
  logger?.debug({
1351
- entrypoint: entrypoint$1,
1352
- path: path$1,
1353
- namespace: namespace$3,
1378
+ entrypoint,
1379
+ path,
1380
+ namespace,
1354
1381
  skipped,
1355
1382
  visited
1356
1383
  }, "resolve");
1357
- if (namespace$3 === "source" && visited) return;
1384
+ if (namespace === "source" && visited) return;
1358
1385
  resolved.add(key);
1359
1386
  if (skipped) return;
1360
1387
  queue.push({
1361
1388
  type: "resolve",
1362
1389
  args
1363
1390
  });
1364
- getDeferred(namespace$3).enqueue();
1391
+ getDeferred(namespace).enqueue();
1365
1392
  }
1366
1393
  function load(args) {
1367
- const { entrypoint: entrypoint$1, path: path$1, namespace: namespace$3 } = args;
1394
+ const { entrypoint, path, namespace } = args;
1368
1395
  logger?.debug({
1369
- entrypoint: entrypoint$1,
1370
- path: path$1,
1371
- namespace: namespace$3
1396
+ entrypoint,
1397
+ path,
1398
+ namespace
1372
1399
  }, "load");
1373
1400
  queue.push({
1374
1401
  type: "load",
1375
1402
  args
1376
1403
  });
1377
- getDeferred(namespace$3).enqueue();
1404
+ getDeferred(namespace).enqueue();
1378
1405
  }
1379
- function process$1(args) {
1380
- const { entrypoint: entrypoint$1, path: path$1, namespace: namespace$3 } = args;
1406
+ function process(args) {
1407
+ const { entrypoint, path, namespace } = args;
1381
1408
  logger?.debug({
1382
- entrypoint: entrypoint$1,
1383
- path: path$1,
1384
- namespace: namespace$3
1409
+ entrypoint,
1410
+ path,
1411
+ namespace
1385
1412
  }, "process");
1386
1413
  queue.push({
1387
1414
  type: "process",
1388
1415
  args
1389
1416
  });
1390
- getDeferred(namespace$3).enqueue();
1417
+ getDeferred(namespace).enqueue();
1391
1418
  }
1392
1419
  const build = {
1393
1420
  context,
1394
1421
  source,
1395
1422
  resolve: resolve$1,
1396
1423
  load,
1397
- process: process$1,
1424
+ process,
1398
1425
  defer,
1399
- onResolve(filter$2, hook) {
1426
+ onResolve(filter, hook) {
1400
1427
  resolvers.push({
1401
- filter: filter$2,
1428
+ filter,
1402
1429
  hook
1403
1430
  });
1404
1431
  },
1405
- onLoad(filter$2, hook) {
1432
+ onLoad(filter, hook) {
1406
1433
  loaders.push({
1407
- filter: filter$2,
1434
+ filter,
1408
1435
  hook
1409
1436
  });
1410
1437
  },
1411
- onProcess(filter$2, hook) {
1438
+ onProcess(filter, hook) {
1412
1439
  processors.push({
1413
- filter: filter$2,
1440
+ filter,
1414
1441
  hook
1415
1442
  });
1416
1443
  }
@@ -1420,20 +1447,20 @@ async function run(entrypoint, { config, logger }) {
1420
1447
  logger?.debug({ plugin: plugin.name }, "setting up plugin");
1421
1448
  plugin.setup(build);
1422
1449
  }
1423
- for (const path$1 of await getPaths(entrypoint)) source(path$1);
1450
+ for (const path of await getPaths(entrypoint)) source(path);
1424
1451
  async function processTask(task) {
1425
1452
  const { type } = task;
1426
1453
  let args = task.args;
1427
- const { entrypoint: entrypoint$1, path: path$1, namespace: namespace$3 } = args;
1454
+ const { entrypoint, path, namespace } = args;
1428
1455
  logger?.trace({
1429
1456
  type,
1430
- entrypoint: entrypoint$1,
1431
- path: path$1,
1432
- namespace: namespace$3
1457
+ entrypoint,
1458
+ path,
1459
+ namespace
1433
1460
  }, "processing task");
1434
- for (const { filter: filter$2, hook } of hooks[type]) {
1435
- if (filter$2.namespace !== namespace$3) continue;
1436
- if (filter$2.filter && !filter$2.filter.test(path$1)) continue;
1461
+ for (const { filter, hook } of hooks[type]) {
1462
+ if (filter.namespace !== namespace) continue;
1463
+ if (filter.filter && !filter.filter.test(path)) continue;
1437
1464
  const result = await hook(args);
1438
1465
  if (result !== void 0) {
1439
1466
  args = result;
@@ -1442,9 +1469,9 @@ async function run(entrypoint, { config, logger }) {
1442
1469
  }
1443
1470
  if (args !== void 0) {
1444
1471
  if (type === "resolve") load(args);
1445
- else if (type === "load") process$1(args);
1472
+ else if (type === "load") process(args);
1446
1473
  }
1447
- getDeferred(namespace$3).dequeue();
1474
+ getDeferred(namespace).dequeue();
1448
1475
  }
1449
1476
  while (queue.length || Array.from(pending.values()).some((d) => d.pending > 0)) {
1450
1477
  while (queue.length) {
@@ -1457,7 +1484,7 @@ async function run(entrypoint, { config, logger }) {
1457
1484
  }
1458
1485
  logger?.info(entrypoint, "extraction completed");
1459
1486
  }
1460
-
1461
1487
  //#endregion
1462
- export { cleanup, core, po, react, run };
1463
- //# sourceMappingURL=run-C8z_uhxb.js.map
1488
+ export { cleanup as a, core as i, react as n, po as r, run as t };
1489
+
1490
+ //# sourceMappingURL=run-Bv3fv1N8.mjs.map