@let-value/translate-extract 1.0.11 → 1.0.13
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 +8 -7
- package/dist/bin/cli.d.cts +1 -2
- package/dist/bin/cli.d.ts +1 -2
- package/dist/bin/cli.js +8 -7
- package/dist/bin/cli.js.map +1 -1
- package/dist/{run-XkKxn8kJ.cjs → run-BFehT9l8.cjs} +43 -18
- package/dist/{run-Dl-tr2kf.js → run-CQoAsNNE.js} +45 -20
- package/dist/run-CQoAsNNE.js.map +1 -0
- package/dist/src/index.cjs +114 -71
- package/dist/src/index.d.cts.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +114 -71
- package/dist/src/index.js.map +1 -1
- package/package.json +6 -6
- package/dist/run-Dl-tr2kf.js.map +0 -1
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { run } from "../run-
|
|
1
|
+
import { run } from "../run-CQoAsNNE.js";
|
|
2
2
|
import path, { basename, dirname, extname, join, relative, resolve } from "node:path";
|
|
3
3
|
import fs, { readFile } from "node:fs/promises";
|
|
4
4
|
import * as gettextParser from "gettext-parser";
|
|
@@ -10,6 +10,7 @@ import { ResolverFactory } from "oxc-resolver";
|
|
|
10
10
|
import { getFormula, getNPlurals } from "plural-forms";
|
|
11
11
|
|
|
12
12
|
//#region src/plugins/cleanup/cleanup.ts
|
|
13
|
+
const namespace$2 = "cleanup";
|
|
13
14
|
function cleanup() {
|
|
14
15
|
return {
|
|
15
16
|
name: "cleanup",
|
|
@@ -18,14 +19,14 @@ function cleanup() {
|
|
|
18
19
|
const processedDirs = /* @__PURE__ */ new Set();
|
|
19
20
|
const generated = /* @__PURE__ */ new Set();
|
|
20
21
|
build.onResolve({
|
|
21
|
-
namespace:
|
|
22
|
+
namespace: namespace$2,
|
|
22
23
|
filter: /.*/
|
|
23
24
|
}, (args) => {
|
|
24
25
|
generated.add(args.path);
|
|
25
26
|
return args;
|
|
26
27
|
});
|
|
27
28
|
build.onProcess({
|
|
28
|
-
namespace:
|
|
29
|
+
namespace: namespace$2,
|
|
29
30
|
filter: /.*/
|
|
30
31
|
}, async ({ path: path$1 }) => {
|
|
31
32
|
await build.defer("translate");
|
|
@@ -39,14 +40,12 @@ function cleanup() {
|
|
|
39
40
|
const contents = await fs.readFile(full).catch(() => void 0);
|
|
40
41
|
if (!contents) continue;
|
|
41
42
|
const parsed = gettextParser.po.parse(contents);
|
|
42
|
-
|
|
43
|
-
if (hasTranslations) build.context.logger?.warn({ path: full }, "stray translation file");
|
|
43
|
+
if (Object.entries(parsed.translations || {}).some(([ctx, msgs]) => Object.keys(msgs).some((id) => !(ctx === "" && id === "")))) build.context.logger?.warn({ path: full }, "stray translation file");
|
|
44
44
|
else {
|
|
45
45
|
await fs.unlink(full);
|
|
46
46
|
build.context.logger?.info({ path: full }, "removed empty translation file");
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
return void 0;
|
|
50
49
|
});
|
|
51
50
|
}
|
|
52
51
|
};
|
|
@@ -56,8 +55,7 @@ function cleanup() {
|
|
|
56
55
|
//#region src/plugins/core/queries/comment.ts
|
|
57
56
|
function getReference(node, { path: path$1 }) {
|
|
58
57
|
const line = node.startPosition.row + 1;
|
|
59
|
-
|
|
60
|
-
return `${rel}:${line}`;
|
|
58
|
+
return `${relative(process.cwd(), path$1).replace(/\\+/g, "/")}:${line}`;
|
|
61
59
|
}
|
|
62
60
|
function getComment(node) {
|
|
63
61
|
const text = node.text;
|
|
@@ -109,8 +107,7 @@ const importQuery = {
|
|
|
109
107
|
]
|
|
110
108
|
`,
|
|
111
109
|
extract(match) {
|
|
112
|
-
|
|
113
|
-
return node?.text;
|
|
110
|
+
return (match.captures.find((c) => c.name === "import")?.node)?.text;
|
|
114
111
|
}
|
|
115
112
|
};
|
|
116
113
|
|
|
@@ -152,7 +149,7 @@ const notInPlural = (query) => ({
|
|
|
152
149
|
"ngettext",
|
|
153
150
|
"pgettext",
|
|
154
151
|
"npgettext"
|
|
155
|
-
].includes(fn.childForFieldName("property")?.text ?? "")) return
|
|
152
|
+
].includes(fn.childForFieldName("property")?.text ?? "")) return;
|
|
156
153
|
}
|
|
157
154
|
}
|
|
158
155
|
return result;
|
|
@@ -180,7 +177,7 @@ const messageArg = `[
|
|
|
180
177
|
const messageArgs = `[ (arguments ${messageArg}) (template_string) @tpl ]`;
|
|
181
178
|
const extractMessage = (name) => (match) => {
|
|
182
179
|
const node = match.captures.find((c) => c.name === "call")?.node;
|
|
183
|
-
if (!node) return
|
|
180
|
+
if (!node) return;
|
|
184
181
|
const msgid = match.captures.find((c) => c.name === "msgid")?.node.text;
|
|
185
182
|
if (msgid) return {
|
|
186
183
|
node,
|
|
@@ -211,13 +208,12 @@ const extractMessage = (name) => (match) => {
|
|
|
211
208
|
const id = match.captures.find((c) => c.name === "id")?.node.text;
|
|
212
209
|
const message = match.captures.find((c) => c.name === "message")?.node.text;
|
|
213
210
|
const msgId = id ?? message;
|
|
214
|
-
if (!msgId) return
|
|
215
|
-
const msgstr = message ?? id ?? "";
|
|
211
|
+
if (!msgId) return;
|
|
216
212
|
return {
|
|
217
213
|
node,
|
|
218
214
|
translation: {
|
|
219
215
|
id: msgId,
|
|
220
|
-
message: [
|
|
216
|
+
message: [message ?? id ?? ""]
|
|
221
217
|
}
|
|
222
218
|
};
|
|
223
219
|
};
|
|
@@ -235,8 +231,8 @@ const messageInvalidQuery = notInPlural({
|
|
|
235
231
|
extract(match) {
|
|
236
232
|
const call = match.captures.find((c) => c.name === "call")?.node;
|
|
237
233
|
const node = match.captures.find((c) => c.name === "arg")?.node;
|
|
238
|
-
if (!call || !node) return
|
|
239
|
-
if (allowed$1.has(node.type)) return
|
|
234
|
+
if (!call || !node) return;
|
|
235
|
+
if (allowed$1.has(node.type)) return;
|
|
240
236
|
return {
|
|
241
237
|
node,
|
|
242
238
|
error: "message() argument must be a string literal, object literal, or template literal"
|
|
@@ -249,7 +245,7 @@ const messageInvalidQuery = notInPlural({
|
|
|
249
245
|
const extractPluralForms = (name) => (match) => {
|
|
250
246
|
const call = match.captures.find((c) => c.name === "call")?.node;
|
|
251
247
|
const n = match.captures.find((c) => c.name === "n")?.node;
|
|
252
|
-
if (!call || !n || n.nextNamedSibling) return
|
|
248
|
+
if (!call || !n || n.nextNamedSibling) return;
|
|
253
249
|
const msgctxt = match.captures.find((c) => c.name === "msgctxt")?.node?.text;
|
|
254
250
|
const msgNodes = match.captures.filter((c) => c.name === "msg").map((c) => c.node);
|
|
255
251
|
const ids = [];
|
|
@@ -279,7 +275,7 @@ const extractPluralForms = (name) => (match) => {
|
|
|
279
275
|
strs.push(result.translation.message[0] ?? "");
|
|
280
276
|
}
|
|
281
277
|
}
|
|
282
|
-
if (ids.length === 0) return
|
|
278
|
+
if (ids.length === 0) return;
|
|
283
279
|
const translation = {
|
|
284
280
|
id: ids[0],
|
|
285
281
|
plural: ids[1],
|
|
@@ -340,12 +336,12 @@ const contextInvalidQuery = withComment({
|
|
|
340
336
|
pattern: ctxCall,
|
|
341
337
|
extract(match) {
|
|
342
338
|
const call = match.captures.find((c) => c.name === "ctx")?.node;
|
|
343
|
-
if (!call) return
|
|
339
|
+
if (!call) return;
|
|
344
340
|
const parent = call.parent;
|
|
345
341
|
if (parent && parent.type === "member_expression" && parent.childForFieldName("object")?.id === call.id) {
|
|
346
342
|
const property = parent.childForFieldName("property")?.text;
|
|
347
343
|
const grandparent = parent.parent;
|
|
348
|
-
if (grandparent && grandparent.type === "call_expression" && grandparent.childForFieldName("function")?.id === parent.id && (property === "message" || property === "plural")) return
|
|
344
|
+
if (grandparent && grandparent.type === "call_expression" && grandparent.childForFieldName("function")?.id === parent.id && (property === "message" || property === "plural")) return;
|
|
349
345
|
}
|
|
350
346
|
return {
|
|
351
347
|
node: call,
|
|
@@ -372,8 +368,8 @@ const gettextInvalidQuery = {
|
|
|
372
368
|
extract(match) {
|
|
373
369
|
const call = match.captures.find((c) => c.name === "call")?.node;
|
|
374
370
|
const node = match.captures.find((c) => c.name === "arg")?.node;
|
|
375
|
-
if (!call || !node) return
|
|
376
|
-
if (allowed.has(node.type)) return
|
|
371
|
+
if (!call || !node) return;
|
|
372
|
+
if (allowed.has(node.type)) return;
|
|
377
373
|
return {
|
|
378
374
|
node,
|
|
379
375
|
error: "gettext() argument must be a string literal, object literal, or template literal"
|
|
@@ -541,7 +537,7 @@ function findTsconfig(dir) {
|
|
|
541
537
|
const config = path.join(current, "tsconfig.json");
|
|
542
538
|
if (fs$1.existsSync(config)) return config;
|
|
543
539
|
const parent = path.dirname(current);
|
|
544
|
-
if (parent === current) return
|
|
540
|
+
if (parent === current) return;
|
|
545
541
|
current = parent;
|
|
546
542
|
}
|
|
547
543
|
}
|
|
@@ -634,7 +630,6 @@ function core() {
|
|
|
634
630
|
namespace: "translate",
|
|
635
631
|
data: translations
|
|
636
632
|
});
|
|
637
|
-
return void 0;
|
|
638
633
|
});
|
|
639
634
|
}
|
|
640
635
|
};
|
|
@@ -780,7 +775,7 @@ function po() {
|
|
|
780
775
|
filter: /.*/,
|
|
781
776
|
namespace
|
|
782
777
|
}, async ({ entrypoint, path: path$1, data }) => {
|
|
783
|
-
if (!data || !Array.isArray(data)) return
|
|
778
|
+
if (!data || !Array.isArray(data)) return;
|
|
784
779
|
for (const locale of build.context.config.locales) {
|
|
785
780
|
const destination = build.context.config.destination({
|
|
786
781
|
entrypoint,
|
|
@@ -802,7 +797,6 @@ function po() {
|
|
|
802
797
|
namespace
|
|
803
798
|
});
|
|
804
799
|
});
|
|
805
|
-
return void 0;
|
|
806
800
|
});
|
|
807
801
|
build.onLoad({
|
|
808
802
|
filter: /.*\.po$/,
|
|
@@ -823,7 +817,7 @@ function po() {
|
|
|
823
817
|
const collected = collections.get(path$1);
|
|
824
818
|
if (!collected) {
|
|
825
819
|
build.context.logger?.warn({ path: path$1 }, "no translations collected for this path");
|
|
826
|
-
return
|
|
820
|
+
return;
|
|
827
821
|
}
|
|
828
822
|
const { locale, translations } = collected;
|
|
829
823
|
const record = collect(translations, locale);
|
|
@@ -880,8 +874,7 @@ function resolvePlugins(user) {
|
|
|
880
874
|
function defineConfig(config) {
|
|
881
875
|
const defaultLocale = config.defaultLocale ?? "en";
|
|
882
876
|
const plugins = resolvePlugins(config.plugins);
|
|
883
|
-
const
|
|
884
|
-
const entrypoints = raw.map(resolveEntrypoint);
|
|
877
|
+
const entrypoints = (Array.isArray(config.entrypoints) ? config.entrypoints : [config.entrypoints]).map(resolveEntrypoint);
|
|
885
878
|
return {
|
|
886
879
|
plugins,
|
|
887
880
|
entrypoints,
|
|
@@ -898,43 +891,96 @@ function defineConfig(config) {
|
|
|
898
891
|
//#endregion
|
|
899
892
|
//#region src/plugins/react/queries/utils.ts
|
|
900
893
|
function buildTemplate(node) {
|
|
894
|
+
const source = node.tree.rootNode.text;
|
|
895
|
+
const open = node.childForFieldName("open_tag");
|
|
896
|
+
const close = node.childForFieldName("close_tag");
|
|
897
|
+
const contentStart = open?.endIndex ?? node.startIndex;
|
|
898
|
+
const contentEnd = close?.startIndex ?? node.endIndex;
|
|
899
|
+
const parts = [];
|
|
900
|
+
let segmentStart = contentStart;
|
|
901
|
+
const pushRawText = (endIndex) => {
|
|
902
|
+
if (endIndex <= segmentStart) {
|
|
903
|
+
segmentStart = Math.max(segmentStart, endIndex);
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
const text$1 = source.slice(segmentStart, endIndex);
|
|
907
|
+
if (text$1) parts.push({
|
|
908
|
+
kind: "text",
|
|
909
|
+
text: text$1,
|
|
910
|
+
raw: true
|
|
911
|
+
});
|
|
912
|
+
segmentStart = endIndex;
|
|
913
|
+
};
|
|
901
914
|
const children = node.namedChildren.slice(1, -1);
|
|
902
|
-
const
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
} else if (expr.type === "string") strings[strings.length - 1] += expr.text.slice(1, -1);
|
|
921
|
-
else if (expr.type === "template_string") {
|
|
922
|
-
const hasSubstitutions = expr.children.some((c) => c.type === "template_substitution");
|
|
923
|
-
if (hasSubstitutions) return {
|
|
924
|
-
text: "",
|
|
925
|
-
error: "JSX expressions with template substitutions are not supported"
|
|
926
|
-
};
|
|
927
|
-
const content = expr.text.slice(1, -1);
|
|
928
|
-
strings[strings.length - 1] += content;
|
|
929
|
-
} else return {
|
|
915
|
+
for (const child of children) if (child.type === "jsx_expression") {
|
|
916
|
+
pushRawText(child.startIndex);
|
|
917
|
+
const expr = child.namedChildren[0];
|
|
918
|
+
if (!expr) return {
|
|
919
|
+
text: "",
|
|
920
|
+
error: "Empty JSX expression"
|
|
921
|
+
};
|
|
922
|
+
if (expr.type === "identifier") parts.push({
|
|
923
|
+
kind: "expr",
|
|
924
|
+
value: expr.text
|
|
925
|
+
});
|
|
926
|
+
else if (expr.type === "string") parts.push({
|
|
927
|
+
kind: "text",
|
|
928
|
+
text: expr.text.slice(1, -1),
|
|
929
|
+
raw: false
|
|
930
|
+
});
|
|
931
|
+
else if (expr.type === "template_string") {
|
|
932
|
+
if (expr.children.some((c) => c.type === "template_substitution")) return {
|
|
930
933
|
text: "",
|
|
931
|
-
error: "JSX expressions
|
|
934
|
+
error: "JSX expressions with template substitutions are not supported"
|
|
932
935
|
};
|
|
933
|
-
|
|
934
|
-
|
|
936
|
+
parts.push({
|
|
937
|
+
kind: "text",
|
|
938
|
+
text: expr.text.slice(1, -1),
|
|
939
|
+
raw: false
|
|
940
|
+
});
|
|
941
|
+
} else return {
|
|
935
942
|
text: "",
|
|
936
|
-
error: "
|
|
943
|
+
error: "JSX expressions must be simple identifiers, strings, or template literals"
|
|
937
944
|
};
|
|
945
|
+
segmentStart = child.endIndex;
|
|
946
|
+
} else if (child.type === "string") {
|
|
947
|
+
pushRawText(child.startIndex);
|
|
948
|
+
parts.push({
|
|
949
|
+
kind: "text",
|
|
950
|
+
text: child.text.slice(1, -1),
|
|
951
|
+
raw: false
|
|
952
|
+
});
|
|
953
|
+
segmentStart = child.endIndex;
|
|
954
|
+
} else if (child.type === "jsx_text" || child.type === "html_character_reference" || child.isError) continue;
|
|
955
|
+
else return {
|
|
956
|
+
text: "",
|
|
957
|
+
error: "Unsupported JSX child"
|
|
958
|
+
};
|
|
959
|
+
pushRawText(contentEnd);
|
|
960
|
+
const firstRawIndex = parts.findIndex((part) => part.kind === "text" && part.raw);
|
|
961
|
+
if (firstRawIndex === 0) {
|
|
962
|
+
const part = parts[firstRawIndex];
|
|
963
|
+
part.text = part.text.replace(/^\s+/, "");
|
|
964
|
+
}
|
|
965
|
+
let lastRawIndex = -1;
|
|
966
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
967
|
+
const part = parts[i];
|
|
968
|
+
if (part.kind === "text" && part.raw) {
|
|
969
|
+
lastRawIndex = i;
|
|
970
|
+
break;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
if (lastRawIndex !== -1 && lastRawIndex === parts.length - 1) {
|
|
974
|
+
const part = parts[lastRawIndex];
|
|
975
|
+
part.text = part.text.replace(/\s+$/, "");
|
|
976
|
+
}
|
|
977
|
+
const strings = [""];
|
|
978
|
+
const values = [];
|
|
979
|
+
for (const part of parts) if (part.kind === "text") {
|
|
980
|
+
if (part.text) strings[strings.length - 1] += part.text;
|
|
981
|
+
} else {
|
|
982
|
+
values.push(part.value);
|
|
983
|
+
strings.push("");
|
|
938
984
|
}
|
|
939
985
|
let text = "";
|
|
940
986
|
for (let i = 0; i < strings.length; i++) {
|
|
@@ -954,13 +1000,11 @@ function buildAttrValue(node) {
|
|
|
954
1000
|
if (expr.type === "identifier") return { text: `\${${expr.text}}` };
|
|
955
1001
|
else if (expr.type === "string") return { text: expr.text.slice(1, -1) };
|
|
956
1002
|
else if (expr.type === "template_string") {
|
|
957
|
-
|
|
958
|
-
if (hasSubstitutions) return {
|
|
1003
|
+
if (expr.children.some((c) => c.type === "template_substitution")) return {
|
|
959
1004
|
text: "",
|
|
960
1005
|
error: "JSX expressions with template substitutions are not supported"
|
|
961
1006
|
};
|
|
962
|
-
|
|
963
|
-
return { text: content };
|
|
1007
|
+
return { text: expr.text.slice(1, -1) };
|
|
964
1008
|
} else return {
|
|
965
1009
|
text: "",
|
|
966
1010
|
error: "JSX expressions must be simple identifiers, strings, or template literals"
|
|
@@ -1150,22 +1194,22 @@ function react() {
|
|
|
1150
1194
|
build.onResolve({
|
|
1151
1195
|
filter: /.*/,
|
|
1152
1196
|
namespace: "source"
|
|
1153
|
-
}, ({ entrypoint, path: path$1, namespace: namespace$
|
|
1197
|
+
}, ({ entrypoint, path: path$1, namespace: namespace$3 }) => {
|
|
1154
1198
|
return {
|
|
1155
1199
|
entrypoint,
|
|
1156
|
-
namespace: namespace$
|
|
1200
|
+
namespace: namespace$3,
|
|
1157
1201
|
path: resolve(path$1)
|
|
1158
1202
|
};
|
|
1159
1203
|
});
|
|
1160
1204
|
build.onLoad({
|
|
1161
1205
|
filter,
|
|
1162
1206
|
namespace: "source"
|
|
1163
|
-
}, async ({ entrypoint, path: path$1, namespace: namespace$
|
|
1207
|
+
}, async ({ entrypoint, path: path$1, namespace: namespace$3 }) => {
|
|
1164
1208
|
const data = await readFile(path$1, "utf8");
|
|
1165
1209
|
return {
|
|
1166
1210
|
entrypoint,
|
|
1167
1211
|
path: path$1,
|
|
1168
|
-
namespace: namespace$
|
|
1212
|
+
namespace: namespace$3,
|
|
1169
1213
|
data
|
|
1170
1214
|
};
|
|
1171
1215
|
});
|
|
@@ -1181,7 +1225,6 @@ function react() {
|
|
|
1181
1225
|
namespace: "translate",
|
|
1182
1226
|
data: translations
|
|
1183
1227
|
});
|
|
1184
|
-
return void 0;
|
|
1185
1228
|
});
|
|
1186
1229
|
}
|
|
1187
1230
|
};
|