@let-value/translate-extract 1.0.30 → 1.0.31

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.
@@ -1,1321 +1,10 @@
1
- const require_run = require('../run-BonabcP6.cjs');
2
- let node_util = require("node:util");
3
- node_util = require_run.__toESM(node_util);
4
- let node_path = require("node:path");
5
- node_path = require_run.__toESM(node_path);
6
- let node_fs_promises = require("node:fs/promises");
7
- node_fs_promises = require_run.__toESM(node_fs_promises);
8
- let gettext_parser = require("gettext-parser");
9
- gettext_parser = require_run.__toESM(gettext_parser);
10
- let node_fs = require("node:fs");
11
- node_fs = require_run.__toESM(node_fs);
12
- let tree_sitter = require("tree-sitter");
13
- tree_sitter = require_run.__toESM(tree_sitter);
14
- let tree_sitter_javascript = require("tree-sitter-javascript");
15
- tree_sitter_javascript = require_run.__toESM(tree_sitter_javascript);
16
- let tree_sitter_typescript = require("tree-sitter-typescript");
17
- tree_sitter_typescript = require_run.__toESM(tree_sitter_typescript);
18
- let oxc_resolver = require("oxc-resolver");
19
- oxc_resolver = require_run.__toESM(oxc_resolver);
20
- let plural_forms = require("plural-forms");
21
- plural_forms = require_run.__toESM(plural_forms);
22
-
23
- //#region src/plugins/cleanup/cleanup.ts
24
- const namespace$2 = "cleanup";
25
- function cleanup() {
26
- return {
27
- name: "cleanup",
28
- setup(build) {
29
- build.context.logger?.debug("cleanup plugin initialized");
30
- const processed = /* @__PURE__ */ new Set();
31
- const generated = /* @__PURE__ */ new Set();
32
- const dirs = /* @__PURE__ */ new Set();
33
- let dispatched = false;
34
- build.onResolve({
35
- namespace: namespace$2,
36
- filter: /.*/
37
- }, ({ path: path$1 }) => {
38
- generated.add(path$1);
39
- dirs.add((0, node_path.dirname)(path$1));
40
- Promise.all([
41
- build.defer("source"),
42
- build.defer("translate"),
43
- build.defer(namespace$2)
44
- ]).then(() => {
45
- if (dispatched) return;
46
- dispatched = true;
47
- for (const path$2 of dirs.values()) build.process({
48
- entrypoint: path$2,
49
- path: path$2,
50
- namespace: namespace$2,
51
- data: void 0
52
- });
53
- });
54
- });
55
- build.onProcess({
56
- namespace: namespace$2,
57
- filter: /.*/
58
- }, async ({ path: path$1 }) => {
59
- if (processed.has(path$1)) return;
60
- processed.add(path$1);
61
- const files = await node_fs_promises.default.readdir(path$1).catch(() => []);
62
- for (const f of files.filter((p) => p.endsWith(".po"))) {
63
- const full = (0, node_path.join)(path$1, f);
64
- const contents = await node_fs_promises.default.readFile(full).catch(() => void 0);
65
- if (!contents) continue;
66
- const parsed = gettext_parser.po.parse(contents);
67
- const hasTranslations = Object.entries(parsed.translations || {}).some(([ctx, msgs]) => Object.keys(msgs).some((id) => !(ctx === "" && id === "")));
68
- if (!hasTranslations && generated.has(full)) await node_fs_promises.default.unlink(full);
69
- if (hasTranslations && !generated.has(full)) build.context.logger?.warn({ path: full }, "stray translation file");
70
- }
71
- });
72
- }
73
- };
74
- }
75
-
76
- //#endregion
77
- //#region src/plugins/core/queries/comment.ts
78
- function getReference(node, { path: path$1 }) {
79
- const line = node.startPosition.row + 1;
80
- return `${(0, node_path.relative)(process.cwd(), path$1).replace(/\\+/g, "/")}:${line}`;
81
- }
82
- function getComment(node) {
83
- const text = node.text;
84
- if (text.startsWith("/*")) return text.slice(2, -2).replace(/^\s*\*?\s*/gm, "").trim();
85
- return text.replace(/^\/\/\s?/, "").trim();
86
- }
87
- const withComment = (query) => ({
88
- pattern: `(
89
- ((comment) @comment)?
90
- .
91
- (_ ${query.pattern})
92
- )`,
93
- extract(match) {
94
- const result = query.extract(match);
95
- if (!result?.translation) return result;
96
- const comment = match.captures.find((c) => c.name === "comment")?.node;
97
- if (!comment) return result;
98
- if (comment) result.translation.comments = {
99
- ...result.translation.comments,
100
- extracted: getComment(comment)
101
- };
102
- return result;
103
- }
104
- });
105
-
106
- //#endregion
107
- //#region src/plugins/core/queries/import.ts
108
- const importQuery = {
109
- pattern: `
110
- [
111
- (import_statement
112
- source: (string (string_fragment) @import))
113
- (export_statement
114
- source: (string (string_fragment) @import))
115
- (call_expression
116
- function: (identifier) @func
117
- arguments: (arguments (string (string_fragment) @import))
118
- (#eq? @func "require"))
119
- (call_expression
120
- function: (member_expression
121
- object: (identifier) @obj
122
- property: (property_identifier) @method)
123
- arguments: (arguments (string (string_fragment) @import))
124
- (#eq? @obj "require")
125
- (#eq? @method "resolve"))
126
- (call_expression
127
- function: (import)
128
- arguments: (arguments (string (string_fragment) @import)))
129
- ]
130
- `,
131
- extract(match) {
132
- return (match.captures.find((c) => c.name === "import")?.node)?.text;
133
- }
134
- };
135
-
136
- //#endregion
137
- //#region src/plugins/core/queries/utils.ts
138
- const callPattern = (fnName, args, allowMember = true) => `(
139
- (call_expression
140
- function: ${allowMember ? `[
141
- (identifier) @func
142
- (member_expression property: (property_identifier) @func)
143
- ]` : `(identifier) @func`}
144
- arguments: ${args}
145
- ) @call
146
- (#eq? @func "${fnName}")
147
- )`;
148
- function isDescendant(node, ancestor) {
149
- let current = node;
150
- while (current) {
151
- if (current.id === ancestor.id) return true;
152
- current = current.parent;
153
- }
154
- return false;
155
- }
156
-
157
- //#endregion
158
- //#region src/plugins/core/queries/message.ts
159
- const notInPlural = (query) => ({
160
- pattern: query.pattern,
161
- extract(match) {
162
- const result = query.extract(match);
163
- if (!result?.node) return result;
164
- let parent = result.node.parent;
165
- if (parent && parent.type === "arguments") parent = parent.parent;
166
- if (parent && parent.type === "call_expression") {
167
- const fn = parent.childForFieldName("function");
168
- if (fn) {
169
- if (fn.type === "identifier" && (fn.text === "plural" || fn.text === "ngettext" || fn.text === "pgettext" || fn.text === "npgettext") || fn.type === "member_expression" && [
170
- "plural",
171
- "ngettext",
172
- "pgettext",
173
- "npgettext"
174
- ].includes(fn.childForFieldName("property")?.text ?? "")) return;
175
- }
176
- }
177
- return result;
178
- }
179
- });
180
- const messageArg = `[
181
- (string (string_fragment) @msgid)
182
- (object
183
- (_)*
184
- (pair
185
- key: (property_identifier) @id_key
186
- value: (string (string_fragment) @id)
187
- (#eq? @id_key "id")
188
- )?
189
- (_)*
190
- (pair
191
- key: (property_identifier) @msg_key
192
- value: (string (string_fragment) @message)
193
- (#eq? @msg_key "message")
194
- )?
195
- (_)*
196
- )
197
- (template_string) @tpl
198
- ]`;
199
- const messageArgs = `[ (arguments ${messageArg}) (template_string) @tpl ]`;
200
- const extractMessage = (name) => (match) => {
201
- const node = match.captures.find((c) => c.name === "call")?.node;
202
- if (!node) return;
203
- const msgid = match.captures.find((c) => c.name === "msgid")?.node.text;
204
- if (msgid) return {
205
- node,
206
- translation: {
207
- id: msgid,
208
- message: [msgid]
209
- }
210
- };
211
- const tpl = match.captures.find((c) => c.name === "tpl")?.node;
212
- if (tpl) {
213
- for (const child of tpl.children) {
214
- if (child.type !== "template_substitution") continue;
215
- const expr = child.namedChildren[0];
216
- if (!expr || expr.type !== "identifier") return {
217
- node,
218
- error: `${name}() template expressions must be simple identifiers`
219
- };
220
- }
221
- const text = tpl.text.slice(1, -1);
222
- return {
223
- node,
224
- translation: {
225
- id: text,
226
- message: [text]
227
- }
228
- };
229
- }
230
- const id = match.captures.find((c) => c.name === "id")?.node.text;
231
- const message = match.captures.find((c) => c.name === "message")?.node.text;
232
- const msgId = id ?? message;
233
- if (!msgId) return;
234
- return {
235
- node,
236
- translation: {
237
- id: msgId,
238
- message: [message ?? id ?? ""]
239
- }
240
- };
241
- };
242
- const messageQuery$1 = notInPlural(withComment({
243
- pattern: callPattern("message", messageArgs),
244
- extract: extractMessage("message")
245
- }));
246
- const allowed$1 = new Set([
247
- "string",
248
- "object",
249
- "template_string"
250
- ]);
251
- const messageInvalidQuery = notInPlural({
252
- pattern: callPattern("message", "(arguments (_) @arg)"),
253
- extract(match) {
254
- const call = match.captures.find((c) => c.name === "call")?.node;
255
- const node = match.captures.find((c) => c.name === "arg")?.node;
256
- if (!call || !node) return;
257
- if (allowed$1.has(node.type)) return;
258
- return {
259
- node,
260
- error: "message() argument must be a string literal, object literal, or template literal"
261
- };
262
- }
263
- });
264
-
265
- //#endregion
266
- //#region src/plugins/core/queries/plural-utils.ts
267
- const extractPluralForms = (name) => (match) => {
268
- const call = match.captures.find((c) => c.name === "call")?.node;
269
- const n = match.captures.find((c) => c.name === "n")?.node;
270
- if (!call || !n || n.nextNamedSibling) return;
271
- const msgctxt = match.captures.find((c) => c.name === "msgctxt")?.node?.text;
272
- const msgNodes = match.captures.filter((c) => c.name === "msg").map((c) => c.node);
273
- const ids = [];
274
- const strs = [];
275
- for (const node of msgNodes) {
276
- const relevant = match.captures.filter((c) => [
277
- "msgid",
278
- "id",
279
- "message",
280
- "tpl"
281
- ].includes(c.name) && isDescendant(c.node, node));
282
- const subMatch = {
283
- pattern: 0,
284
- captures: [{
285
- name: "call",
286
- node
287
- }, ...relevant]
288
- };
289
- const result = extractMessage(name)(subMatch);
290
- if (!result) continue;
291
- if (result.error) return {
292
- node: call,
293
- error: result.error
294
- };
295
- if (result.translation) {
296
- ids.push(result.translation.id);
297
- strs.push(result.translation.message[0] ?? "");
298
- }
299
- }
300
- if (ids.length === 0) return;
301
- const translation = {
302
- id: ids[0],
303
- plural: ids[1],
304
- message: strs
305
- };
306
- if (msgctxt) translation.context = msgctxt;
307
- return {
308
- node: call,
309
- translation
310
- };
311
- };
312
-
313
- //#endregion
314
- //#region src/plugins/core/queries/context.ts
315
- const ctxCall = callPattern("context", `[
316
- (arguments (string (string_fragment) @msgctxt))
317
- (template_string) @msgctxt
318
- ]`).replace(/@call/g, "@ctx").replace(/@func/g, "@ctxfn");
319
- const contextMsgQuery = withComment({
320
- pattern: `(
321
- (call_expression
322
- function: (member_expression
323
- object: ${ctxCall}
324
- property: (property_identifier) @func
325
- )
326
- arguments: ${messageArgs}
327
- ) @call
328
- (#eq? @func "message")
329
- )`,
330
- extract(match) {
331
- const result = extractMessage("context.message")(match);
332
- const contextNode = match.captures.find((c) => c.name === "msgctxt")?.node;
333
- if (!result || !result.translation || !contextNode) return result;
334
- if (contextNode.type === "template_string") for (const child of contextNode.children) {
335
- if (child.type !== "template_substitution") continue;
336
- const expr = child.namedChildren[0];
337
- if (!expr || expr.type !== "identifier") return {
338
- node: contextNode,
339
- error: "context() template expressions must be simple identifiers"
340
- };
341
- }
342
- const contextText = contextNode.type === "template_string" ? contextNode.text.slice(1, -1) : contextNode.text;
343
- return {
344
- node: result.node,
345
- translation: {
346
- ...result.translation,
347
- context: contextText
348
- }
349
- };
350
- }
351
- });
352
- const msgCall$3 = callPattern("message", messageArgs, false).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn");
353
- const contextPluralQuery = withComment({
354
- pattern: `(
355
- (call_expression
356
- function: (member_expression
357
- object: ${ctxCall}
358
- property: (property_identifier) @func
359
- )
360
- arguments: (arguments (
361
- (${msgCall$3} ("," )?)+
362
- (number) @n
363
- ))
364
- ) @call
365
- (#eq? @func "plural")
366
- )`,
367
- extract: extractPluralForms("context.plural")
368
- });
369
- const contextInvalidQuery = withComment({
370
- pattern: ctxCall,
371
- extract(match) {
372
- const call = match.captures.find((c) => c.name === "ctx")?.node;
373
- if (!call) return;
374
- const parent = call.parent;
375
- if (parent && parent.type === "member_expression" && parent.childForFieldName("object")?.id === call.id) {
376
- const property = parent.childForFieldName("property")?.text;
377
- const grandparent = parent.parent;
378
- if (grandparent && grandparent.type === "call_expression" && grandparent.childForFieldName("function")?.id === parent.id && (property === "message" || property === "plural")) return;
379
- }
380
- return {
381
- node: call,
382
- error: "context() must be used with message() or plural() in the same expression"
383
- };
384
- }
385
- });
386
-
387
- //#endregion
388
- //#region src/plugins/core/queries/gettext.ts
389
- const gettextQuery = withComment({
390
- pattern: callPattern("gettext", messageArgs),
391
- extract: extractMessage("gettext")
392
- });
393
- const allowed = new Set([
394
- "string",
395
- "object",
396
- "template_string",
397
- "identifier",
398
- "call_expression"
399
- ]);
400
- const gettextInvalidQuery = {
401
- pattern: callPattern("gettext", "(arguments (_) @arg)"),
402
- extract(match) {
403
- const call = match.captures.find((c) => c.name === "call")?.node;
404
- const node = match.captures.find((c) => c.name === "arg")?.node;
405
- if (!call || !node) return;
406
- if (allowed.has(node.type)) return;
407
- return {
408
- node,
409
- error: "gettext() argument must be a string literal, object literal, or template literal"
410
- };
411
- }
412
- };
413
-
414
- //#endregion
415
- //#region src/plugins/core/queries/ngettext.ts
416
- const msgCall$2 = callPattern("message", messageArgs).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn");
417
- const plainMsg$1 = `(${messageArg}) @msg`;
418
- const msgArg$1 = `[${msgCall$2} ${plainMsg$1}]`;
419
- const ngettextQuery = withComment({
420
- pattern: callPattern("ngettext", `(arguments ${msgArg$1} "," ${msgArg$1} ("," ${msgArg$1})* "," (_) @n)`),
421
- extract: extractPluralForms("ngettext")
422
- });
423
-
424
- //#endregion
425
- //#region src/plugins/core/queries/npgettext.ts
426
- const msgCall$1 = callPattern("message", messageArgs).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn");
427
- const plainMsg = `(${messageArg}) @msg`;
428
- const msgArg = `[${msgCall$1} ${plainMsg}]`;
429
- const npgettextQuery = withComment({
430
- pattern: callPattern("npgettext", `(arguments (string (string_fragment) @msgctxt) "," ${msgArg} "," ${msgArg} ("," ${msgArg})* "," (_) @n)`),
431
- extract: extractPluralForms("npgettext")
432
- });
433
-
434
- //#endregion
435
- //#region src/plugins/core/queries/pgettext.ts
436
- const pgettextQuery = withComment({
437
- pattern: callPattern("pgettext", `(arguments (string (string_fragment) @msgctxt) "," ${messageArg})`),
438
- extract(match) {
439
- const result = extractMessage("pgettext")(match);
440
- const contextNode = match.captures.find((c) => c.name === "msgctxt")?.node;
441
- if (!result || !contextNode || !result.translation) return result;
442
- return {
443
- node: result.node,
444
- translation: {
445
- ...result.translation,
446
- context: contextNode.text
447
- }
448
- };
449
- }
450
- });
451
-
452
- //#endregion
453
- //#region src/plugins/core/queries/plural.ts
454
- const msgCall = callPattern("message", messageArgs, false).replace(/@call/g, "@msg").replace(/@func/g, "@msgfn");
455
- const pluralQuery$1 = withComment({
456
- pattern: callPattern("plural", `(arguments (
457
- (${msgCall} ("," )?)+
458
- (number) @n
459
- ))`, false),
460
- extract: extractPluralForms("plural")
461
- });
462
-
463
- //#endregion
464
- //#region src/plugins/core/queries/index.ts
465
- const queries$1 = [
466
- contextMsgQuery,
467
- contextPluralQuery,
468
- contextInvalidQuery,
469
- messageQuery$1,
470
- messageInvalidQuery,
471
- gettextQuery,
472
- gettextInvalidQuery,
473
- pluralQuery$1,
474
- ngettextQuery,
475
- pgettextQuery,
476
- npgettextQuery
477
- ];
478
-
479
- //#endregion
480
- //#region src/plugins/core/parse.ts
481
- function getLanguage(ext) {
482
- switch (ext) {
483
- case ".ts": return tree_sitter_typescript.default.typescript;
484
- case ".tsx": return tree_sitter_typescript.default.tsx;
485
- default: return tree_sitter_javascript.default;
486
- }
487
- }
488
- const parserCache = /* @__PURE__ */ new Map();
489
- const queryCache = /* @__PURE__ */ new WeakMap();
490
- function getCachedParser(ext) {
491
- let cached = parserCache.get(ext);
492
- if (!cached) {
493
- const parser = new tree_sitter.default();
494
- const language = getLanguage(ext);
495
- parser.setLanguage(language);
496
- cached = {
497
- parser,
498
- language
499
- };
500
- parserCache.set(ext, cached);
501
- }
502
- return cached;
503
- }
504
- function getCachedQuery(language, pattern) {
505
- let cache = queryCache.get(language);
506
- if (!cache) {
507
- cache = /* @__PURE__ */ new Map();
508
- queryCache.set(language, cache);
509
- }
510
- let query = cache.get(pattern);
511
- if (!query) {
512
- query = new tree_sitter.default.Query(language, pattern);
513
- cache.set(pattern, query);
514
- }
515
- return query;
516
- }
517
- function getParser(path$1) {
518
- const ext = (0, node_path.extname)(path$1);
519
- return getCachedParser(ext);
520
- }
521
- function getQuery(language, pattern) {
522
- return getCachedQuery(language, pattern);
523
- }
524
- function parseSource$1(source, path$1) {
525
- const context = { path: path$1 };
526
- const { parser, language } = getParser(path$1);
527
- const tree = parser.parse(source);
528
- const translations = [];
529
- const warnings = [];
530
- const imports = [];
531
- const seen = /* @__PURE__ */ new Set();
532
- for (const spec of queries$1) {
533
- const query = getCachedQuery(language, spec.pattern);
534
- for (const match of query.matches(tree.rootNode)) {
535
- const message = spec.extract(match);
536
- if (!message) continue;
537
- const { node, translation, error } = message;
538
- if (seen.has(node.id)) continue;
539
- seen.add(node.id);
540
- const reference = getReference(node, context);
541
- if (translation) translations.push({
542
- ...translation,
543
- comments: {
544
- ...translation.comments,
545
- reference
546
- }
547
- });
548
- if (error) warnings.push({
549
- error,
550
- reference
551
- });
552
- }
553
- }
554
- const importTreeQuery = getCachedQuery(language, importQuery.pattern);
555
- for (const match of importTreeQuery.matches(tree.rootNode)) {
556
- const imp = importQuery.extract(match);
557
- if (imp) imports.push(imp);
558
- }
559
- return {
560
- translations,
561
- imports,
562
- warnings
563
- };
564
- }
565
-
566
- //#endregion
567
- //#region src/plugins/core/resolve.ts
568
- function findTsconfig(dir) {
569
- let current = dir;
570
- while (true) {
571
- const config = node_path.default.join(current, "tsconfig.json");
572
- if (node_fs.default.existsSync(config)) return config;
573
- const parent = node_path.default.dirname(current);
574
- if (parent === current) return;
575
- current = parent;
576
- }
577
- }
578
- const resolverCache = /* @__PURE__ */ new Map();
579
- function getResolver(dir) {
580
- const tsconfig = findTsconfig(dir);
581
- const key = tsconfig ?? "__default__";
582
- let resolver = resolverCache.get(key);
583
- if (!resolver) {
584
- resolver = new oxc_resolver.ResolverFactory({
585
- extensions: [
586
- ".ts",
587
- ".tsx",
588
- ".js",
589
- ".jsx",
590
- ".mjs",
591
- ".cjs",
592
- ".json"
593
- ],
594
- conditionNames: [
595
- "import",
596
- "require",
597
- "node"
598
- ],
599
- ...tsconfig ? { tsconfig: { configFile: tsconfig } } : {}
600
- });
601
- resolverCache.set(key, resolver);
602
- }
603
- return resolver;
604
- }
605
- function resolveImports(file, imports) {
606
- const dir = node_path.default.dirname(node_path.default.resolve(file));
607
- const resolver = getResolver(dir);
608
- const resolved = [];
609
- for (const spec of imports) {
610
- const res = resolver.sync(dir, spec);
611
- if (res.path) resolved.push(res.path);
612
- }
613
- return resolved;
614
- }
615
-
616
- //#endregion
617
- //#region src/plugins/core/core.ts
618
- const filter$1 = /\.([cm]?tsx?|jsx?)$/;
619
- const namespace$1 = "source";
620
- function core() {
621
- return {
622
- name: "core",
623
- setup(build) {
624
- build.context.logger?.debug("core plugin initialized");
625
- build.onResolve({
626
- filter: filter$1,
627
- namespace: namespace$1
628
- }, ({ entrypoint, path: path$1 }) => {
629
- return {
630
- entrypoint,
631
- namespace: namespace$1,
632
- path: (0, node_path.resolve)(path$1)
633
- };
634
- });
635
- build.onLoad({
636
- filter: filter$1,
637
- namespace: namespace$1
638
- }, async ({ entrypoint, path: path$1 }) => {
639
- const data = await (0, node_fs_promises.readFile)(path$1, "utf8");
640
- return {
641
- entrypoint,
642
- path: path$1,
643
- namespace: namespace$1,
644
- data
645
- };
646
- });
647
- build.onProcess({
648
- filter: filter$1,
649
- namespace: namespace$1
650
- }, ({ entrypoint, path: path$1, data }) => {
651
- const { translations, imports, warnings } = parseSource$1(data, path$1);
652
- if (build.context.config.walk) {
653
- const paths = resolveImports(path$1, imports);
654
- for (const path$2 of paths) build.resolve({
655
- entrypoint,
656
- path: path$2,
657
- namespace: namespace$1
658
- });
659
- }
660
- for (const warning of warnings) build.context.logger?.warn(`${warning.error} at ${warning.reference}`);
661
- build.resolve({
662
- entrypoint,
663
- path: path$1,
664
- namespace: "translate",
665
- data: translations
666
- });
667
- });
668
- }
669
- };
670
- }
671
-
672
- //#endregion
673
- //#region src/plugins/po/collect.ts
674
- function collect(source, locale) {
675
- const translations = { "": {} };
676
- const nplurals = locale ? (0, plural_forms.getNPlurals)(locale) : void 0;
677
- for (const { context, id, message, comments, obsolete, plural } of source) {
678
- const ctx = context || "";
679
- if (!translations[ctx]) translations[ctx] = {};
680
- const length = plural ? nplurals ?? message.length : 1;
681
- const existing = translations[ctx][id];
682
- const refs = /* @__PURE__ */ new Set();
683
- if (existing?.comments?.reference) existing.comments.reference.split(/\r?\n|\r/).forEach((r) => {
684
- refs.add(r);
685
- });
686
- if (comments?.reference) comments.reference.split(/\r?\n|\r/).forEach((r) => {
687
- refs.add(r);
688
- });
689
- const msgstr = existing?.msgstr ? existing.msgstr.slice(0, length) : Array.from({ length }, () => "");
690
- while (msgstr.length < length) msgstr.push("");
691
- translations[ctx][id] = {
692
- msgctxt: context || void 0,
693
- msgid: id,
694
- msgid_plural: plural,
695
- msgstr,
696
- comments: {
697
- ...existing?.comments,
698
- ...comments,
699
- reference: refs.size ? Array.from(refs).join("\n") : void 0
700
- },
701
- obsolete: existing?.obsolete ?? obsolete
702
- };
703
- }
704
- return translations;
705
- }
706
-
707
- //#endregion
708
- //#region src/plugins/po/hasChanges.ts
709
- const IGNORED_HEADER_KEYS = new Set(["pot-creation-date", "po-revision-date"]);
710
- const IGNORED_HEADER_LINE_PREFIXES = ["pot-creation-date:", "po-revision-date:"];
711
- function normalizeHeaderString(value) {
712
- const lines = value.split("\n");
713
- const hadTrailingNewline = value.endsWith("\n");
714
- const filtered = lines.filter((line) => {
715
- const trimmed = line.trimStart().toLowerCase();
716
- return !IGNORED_HEADER_LINE_PREFIXES.some((prefix) => trimmed.startsWith(prefix));
717
- }).map((line) => {
718
- const separatorIndex = line.indexOf(":");
719
- if (separatorIndex === -1) return line;
720
- const key = line.slice(0, separatorIndex).trim().toLowerCase();
721
- const value$1 = line.slice(separatorIndex + 1);
722
- return `${key}:${value$1}`;
723
- });
724
- if (hadTrailingNewline && filtered[filtered.length - 1] !== "") filtered.push("");
725
- return filtered.join("\n");
726
- }
727
- function normalize(translations) {
728
- const compiled = gettext_parser.po.compile(translations);
729
- const parsed = gettext_parser.po.parse(compiled);
730
- if (parsed.headers) {
731
- const normalizedHeaders = {};
732
- for (const [key, value] of Object.entries(parsed.headers)) if (!IGNORED_HEADER_KEYS.has(key.toLowerCase())) normalizedHeaders[key.toLowerCase()] = value;
733
- parsed.headers = normalizedHeaders;
734
- }
735
- const headerMessage = parsed.translations?.[""]?.[""];
736
- if (headerMessage?.msgstr) headerMessage.msgstr = headerMessage.msgstr.map((item) => normalizeHeaderString(item));
737
- return parsed;
738
- }
739
- function hasChanges(left, right) {
740
- if (!right) return true;
741
- const normalizedLeft = normalize(left);
742
- const normalizedRight = normalize(right);
743
- return !(0, node_util.isDeepStrictEqual)(normalizedLeft, normalizedRight);
744
- }
745
-
746
- //#endregion
747
- //#region src/plugins/po/merge.ts
748
- function formatDate(date) {
749
- const pad = (n) => n.toString().padStart(2, "0");
750
- const year = date.getFullYear();
751
- const month = pad(date.getMonth() + 1);
752
- const day = pad(date.getDate());
753
- const hours = pad(date.getHours());
754
- const minutes = pad(date.getMinutes());
755
- const tzo = -date.getTimezoneOffset();
756
- const sign = tzo >= 0 ? "+" : "-";
757
- const offsetHours = pad(Math.floor(Math.abs(tzo) / 60));
758
- const offsetMinutes = pad(Math.abs(tzo) % 60);
759
- return `${year}-${month}-${day} ${hours}:${minutes}${sign}${offsetHours}${offsetMinutes}`;
760
- }
761
- function merge(sources, existing, obsolete, locale, generatedAt) {
762
- let headers = {};
763
- let translations = { "": {} };
764
- let obsoleteTranslations = {};
765
- const nplurals = (0, plural_forms.getNPlurals)(locale);
766
- if (existing) {
767
- headers = existing.headers ? structuredClone(existing.headers) : {};
768
- translations = existing.translations ? structuredClone(existing.translations) : { "": {} };
769
- obsoleteTranslations = existing.obsolete ? structuredClone(existing.obsolete) : {};
770
- for (const ctx of Object.keys(translations)) for (const id of Object.keys(translations[ctx])) {
771
- if (ctx === "" && id === "") continue;
772
- translations[ctx][id].obsolete = true;
773
- }
774
- }
775
- const collected = { "": {} };
776
- for (const { translations: translations$1 } of sources) for (const [ctx, msgs] of Object.entries(translations$1)) {
777
- if (!collected[ctx]) collected[ctx] = {};
778
- for (const [id, entry] of Object.entries(msgs)) {
779
- const existing$1 = collected[ctx][id];
780
- const refs = /* @__PURE__ */ new Set();
781
- if (existing$1?.comments?.reference) existing$1.comments.reference.split(/\r?\n|\r/).forEach((r) => {
782
- refs.add(r);
783
- });
784
- if (entry.comments?.reference) entry.comments.reference.split(/\r?\n|\r/).forEach((r) => {
785
- refs.add(r);
786
- });
787
- collected[ctx][id] = {
788
- ...existing$1,
789
- ...entry,
790
- comments: {
791
- ...existing$1?.comments,
792
- ...entry.comments,
793
- reference: refs.size ? Array.from(refs).join("\n") : void 0
794
- }
795
- };
796
- }
797
- }
798
- for (const [ctx, msgs] of Object.entries(collected)) {
799
- if (!translations[ctx]) translations[ctx] = {};
800
- for (const [id, entry] of Object.entries(msgs)) {
801
- const existingEntry = translations[ctx][id] ?? obsoleteTranslations[ctx]?.[id];
802
- if (existingEntry) {
803
- entry.msgstr = existingEntry.msgstr;
804
- entry.comments = {
805
- ...entry.comments,
806
- translator: existingEntry.comments?.translator
807
- };
808
- }
809
- delete entry.obsolete;
810
- entry.msgstr = entry.msgstr.slice(0, nplurals);
811
- while (entry.msgstr.length < nplurals) entry.msgstr.push("");
812
- translations[ctx][id] = entry;
813
- if (obsoleteTranslations[ctx]) delete obsoleteTranslations[ctx][id];
814
- }
815
- }
816
- for (const ctx of Object.keys(translations)) for (const id of Object.keys(translations[ctx])) {
817
- if (ctx === "" && id === "") continue;
818
- const entry = translations[ctx][id];
819
- if (entry.obsolete) {
820
- if (!obsoleteTranslations[ctx]) obsoleteTranslations[ctx] = {};
821
- obsoleteTranslations[ctx][id] = entry;
822
- delete translations[ctx][id];
823
- }
824
- }
825
- headers = {
826
- ...headers,
827
- "Content-Type": headers["Content-Type"] || "text/plain; charset=UTF-8",
828
- "Plural-Forms": `nplurals=${nplurals}; plural=${(0, plural_forms.getFormula)(locale)};`,
829
- language: locale,
830
- "MIME-Version": "1.0",
831
- "Content-Transfer-Encoding": "8bit",
832
- "POT-Creation-Date": formatDate(generatedAt),
833
- "x-generator": "@let-value/translate-extract"
834
- };
835
- return {
836
- charset: "utf-8",
837
- headers,
838
- translations,
839
- ...obsolete === "mark" && Object.keys(obsoleteTranslations).length ? { obsolete: obsoleteTranslations } : {}
840
- };
841
- }
842
-
843
- //#endregion
844
- //#region src/plugins/po/po.ts
845
- const namespace = "translate";
846
- function po() {
847
- return {
848
- name: "po",
849
- setup(build) {
850
- build.context.logger?.debug("po plugin initialized");
851
- const collections = /* @__PURE__ */ new Map();
852
- let dispatched = false;
853
- build.onResolve({
854
- filter: /.*/,
855
- namespace
856
- }, async ({ entrypoint, path: path$1, data }) => {
857
- if (!data || !Array.isArray(data)) return;
858
- for (const locale of build.context.config.locales) {
859
- const destination = build.context.config.destination({
860
- entrypoint,
861
- locale,
862
- path: path$1
863
- });
864
- if (!collections.has(destination)) collections.set(destination, {
865
- locale,
866
- translations: []
867
- });
868
- collections.get(destination)?.translations.push(...data);
869
- }
870
- Promise.all([build.defer("source"), build.defer(namespace)]).then(() => {
871
- if (dispatched) return;
872
- dispatched = true;
873
- for (const path$2 of collections.keys()) build.load({
874
- entrypoint,
875
- path: path$2,
876
- namespace
877
- });
878
- });
879
- });
880
- build.onLoad({
881
- filter: /.*\.po$/,
882
- namespace
883
- }, async ({ entrypoint, path: path$1 }) => {
884
- const contents = await node_fs_promises.default.readFile(path$1).catch(() => void 0);
885
- const data = contents ? gettext_parser.po.parse(contents) : void 0;
886
- return {
887
- entrypoint,
888
- path: path$1,
889
- namespace,
890
- data
891
- };
892
- });
893
- build.onProcess({
894
- filter: /.*\.po$/,
895
- namespace
896
- }, async ({ entrypoint, path: path$1, data }) => {
897
- const collected = collections.get(path$1);
898
- if (!collected) {
899
- build.context.logger?.warn({ path: path$1 }, "no translations collected for this path");
900
- return;
901
- }
902
- const { locale, translations } = collected;
903
- const record = collect(translations, locale);
904
- const out = merge([{ translations: record }], data, build.context.config.obsolete, locale, build.context.generatedAt);
905
- if (hasChanges(out, data)) {
906
- await node_fs_promises.default.mkdir((0, node_path.dirname)(path$1), { recursive: true });
907
- await node_fs_promises.default.writeFile(path$1, gettext_parser.po.compile(out));
908
- }
909
- build.resolve({
910
- entrypoint,
911
- path: path$1,
912
- namespace: "cleanup",
913
- data: translations
914
- });
915
- });
916
- }
917
- };
918
- }
919
-
920
- //#endregion
921
- //#region src/configuration.ts
922
- const defaultPlugins = {
923
- core,
924
- po,
925
- cleanup
926
- };
927
- 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`);
928
- const defaultExclude = [
929
- /(?:^|[\\/])node_modules(?:[\\/]|$)/,
930
- /(?:^|[\\/])dist(?:[\\/]|$)/,
931
- /(?:^|[\\/])build(?:[\\/]|$)/
932
- ];
933
- function normalizeExclude(exclude) {
934
- if (!exclude) return [];
935
- return Array.isArray(exclude) ? exclude : [exclude];
936
- }
937
- function resolveEntrypoint(ep) {
938
- if (typeof ep === "string") return { entrypoint: ep };
939
- const { entrypoint, destination, obsolete, walk, exclude } = ep;
940
- return {
941
- entrypoint,
942
- destination,
943
- obsolete,
944
- walk,
945
- exclude: exclude ? normalizeExclude(exclude) : void 0
946
- };
947
- }
948
- function resolvePlugins(user) {
949
- if (typeof user === "function") return user(defaultPlugins);
950
- if (Array.isArray(user)) return [...Object.values(defaultPlugins).map((plugin) => plugin()), ...user];
951
- return Object.values(defaultPlugins).map((plugin) => plugin());
952
- }
953
- /**
954
- * Type helper to make it easier to use translate.config.ts
955
- * @param config - {@link UserConfig}.
956
- */
957
- function defineConfig(config) {
958
- const defaultLocale = config.defaultLocale ?? "en";
959
- const plugins = resolvePlugins(config.plugins);
960
- const entrypoints = (Array.isArray(config.entrypoints) ? config.entrypoints : [config.entrypoints]).map(resolveEntrypoint);
961
- return {
962
- plugins,
963
- entrypoints,
964
- defaultLocale,
965
- locales: config.locales ?? [defaultLocale],
966
- destination: config.destination ?? defaultDestination,
967
- obsolete: config.obsolete ?? "mark",
968
- walk: config.walk ?? true,
969
- logLevel: config.logLevel ?? "info",
970
- exclude: config.exclude ? normalizeExclude(config.exclude) : defaultExclude
971
- };
972
- }
973
-
974
- //#endregion
975
- //#region src/plugins/react/queries/utils.ts
976
- function buildTemplate(node) {
977
- const source = node.tree.rootNode.text;
978
- const open = node.childForFieldName("open_tag");
979
- const close = node.childForFieldName("close_tag");
980
- const contentStart = open?.endIndex ?? node.startIndex;
981
- const contentEnd = close?.startIndex ?? node.endIndex;
982
- const parts = [];
983
- let segmentStart = contentStart;
984
- const pushRawText = (endIndex) => {
985
- if (endIndex <= segmentStart) {
986
- segmentStart = Math.max(segmentStart, endIndex);
987
- return;
988
- }
989
- const text$1 = source.slice(segmentStart, endIndex);
990
- if (text$1) parts.push({
991
- kind: "text",
992
- text: text$1,
993
- raw: true
994
- });
995
- segmentStart = endIndex;
996
- };
997
- const children = node.namedChildren.slice(1, -1);
998
- for (const child of children) if (child.type === "jsx_expression") {
999
- pushRawText(child.startIndex);
1000
- const expr = child.namedChildren[0];
1001
- if (!expr) return {
1002
- text: "",
1003
- error: "Empty JSX expression"
1004
- };
1005
- if (expr.type === "identifier") parts.push({
1006
- kind: "expr",
1007
- value: expr.text
1008
- });
1009
- else if (expr.type === "string") parts.push({
1010
- kind: "text",
1011
- text: expr.text.slice(1, -1),
1012
- raw: false
1013
- });
1014
- else if (expr.type === "template_string") {
1015
- if (expr.children.some((c) => c.type === "template_substitution")) return {
1016
- text: "",
1017
- error: "JSX expressions with template substitutions are not supported"
1018
- };
1019
- parts.push({
1020
- kind: "text",
1021
- text: expr.text.slice(1, -1),
1022
- raw: false
1023
- });
1024
- } else return {
1025
- text: "",
1026
- error: "JSX expressions must be simple identifiers, strings, or template literals"
1027
- };
1028
- segmentStart = child.endIndex;
1029
- } else if (child.type === "string") {
1030
- pushRawText(child.startIndex);
1031
- parts.push({
1032
- kind: "text",
1033
- text: child.text.slice(1, -1),
1034
- raw: false
1035
- });
1036
- segmentStart = child.endIndex;
1037
- } else if (child.type === "jsx_text" || child.type === "html_character_reference" || child.isError) {} else return {
1038
- text: "",
1039
- error: "Unsupported JSX child"
1040
- };
1041
- pushRawText(contentEnd);
1042
- const firstRawIndex = parts.findIndex((part) => part.kind === "text" && part.raw);
1043
- if (firstRawIndex === 0) {
1044
- const part = parts[firstRawIndex];
1045
- part.text = part.text.replace(/^\s+/, "");
1046
- }
1047
- let lastRawIndex = -1;
1048
- for (let i = parts.length - 1; i >= 0; i--) {
1049
- const part = parts[i];
1050
- if (part.kind === "text" && part.raw) {
1051
- lastRawIndex = i;
1052
- break;
1053
- }
1054
- }
1055
- if (lastRawIndex !== -1 && lastRawIndex === parts.length - 1) {
1056
- const part = parts[lastRawIndex];
1057
- part.text = part.text.replace(/\s+$/, "");
1058
- }
1059
- const strings = [""];
1060
- const values = [];
1061
- for (const part of parts) if (part.kind === "text") {
1062
- if (part.text) strings[strings.length - 1] += part.text;
1063
- } else {
1064
- values.push(part.value);
1065
- strings.push("");
1066
- }
1067
- let text = "";
1068
- for (let i = 0; i < strings.length; i++) {
1069
- text += strings[i];
1070
- if (values[i]) text += `\${${values[i]}}`;
1071
- }
1072
- return { text };
1073
- }
1074
- function buildAttrValue(node) {
1075
- if (node.type === "string") return { text: node.text.slice(1, -1) };
1076
- if (node.type === "jsx_expression") {
1077
- const expr = node.namedChildren[0];
1078
- if (!expr) return {
1079
- text: "",
1080
- error: "Empty JSX expression"
1081
- };
1082
- if (expr.type === "identifier") return { text: `\${${expr.text}}` };
1083
- else if (expr.type === "string") return { text: expr.text.slice(1, -1) };
1084
- else if (expr.type === "template_string") {
1085
- if (expr.children.some((c) => c.type === "template_substitution")) return {
1086
- text: "",
1087
- error: "JSX expressions with template substitutions are not supported"
1088
- };
1089
- return { text: expr.text.slice(1, -1) };
1090
- } else return {
1091
- text: "",
1092
- error: "JSX expressions must be simple identifiers, strings, or template literals"
1093
- };
1094
- }
1095
- return {
1096
- text: "",
1097
- error: "Unsupported JSX child"
1098
- };
1099
- }
1100
-
1101
- //#endregion
1102
- //#region src/plugins/react/queries/message.ts
1103
- const messageQuery = withComment({
1104
- pattern: `(
1105
- [
1106
- (jsx_element (jsx_opening_element name: (identifier) @name)) @call
1107
- (jsx_self_closing_element name: (identifier) @name) @call
1108
- (lexical_declaration
1109
- (variable_declarator
1110
- value: [
1111
- (jsx_element (jsx_opening_element name: (identifier) @name)) @call
1112
- (jsx_self_closing_element name: (identifier) @name) @call
1113
- ]
1114
- )
1115
- )
1116
- ]
1117
- (#eq? @name "Message")
1118
- )`,
1119
- extract(match) {
1120
- const node = match.captures.find((c) => c.name === "call")?.node;
1121
- if (!node) return void 0;
1122
- let attrs = [];
1123
- if (node.type === "jsx_element") {
1124
- const open = node.childForFieldName("open_tag");
1125
- if (open) attrs = open.namedChildren;
1126
- } else if (node.type === "jsx_self_closing_element") attrs = node.namedChildren.slice(1);
1127
- let msgctxt;
1128
- let childValue;
1129
- for (const child of attrs) {
1130
- if (child.type !== "jsx_attribute") continue;
1131
- const name = child.child(0);
1132
- const value = child.child(child.childCount - 1);
1133
- if (name?.text === "context" && value?.type === "string") msgctxt = value.text.slice(1, -1);
1134
- else if (name?.text === "children" && value) childValue = value;
1135
- }
1136
- let text = "";
1137
- let error;
1138
- if (node.type === "jsx_element") ({text, error} = buildTemplate(node));
1139
- else if (childValue) ({text, error} = buildAttrValue(childValue));
1140
- if (error) return {
1141
- node,
1142
- error
1143
- };
1144
- if (!text) return void 0;
1145
- const translation = {
1146
- id: text,
1147
- message: [text]
1148
- };
1149
- if (msgctxt) translation.context = msgctxt;
1150
- return {
1151
- node,
1152
- translation
1153
- };
1154
- }
1155
- });
1156
-
1157
- //#endregion
1158
- //#region src/plugins/react/queries/plural.ts
1159
- function parseForms(node) {
1160
- const forms = [];
1161
- if (node.type === "jsx_expression") {
1162
- const arr = node.namedChildren[0];
1163
- if (!arr || arr.type !== "array") return {
1164
- forms: [],
1165
- error: "Plural forms must be an array"
1166
- };
1167
- for (const el of arr.namedChildren) if (el.type === "jsx_element" || el.type === "jsx_fragment") {
1168
- const { text, error } = buildTemplate(el);
1169
- if (error) return {
1170
- forms: [],
1171
- error
1172
- };
1173
- forms.push(text);
1174
- } else if (el.type === "string") forms.push(el.text.slice(1, -1));
1175
- else return {
1176
- forms: [],
1177
- error: "Unsupported plural form"
1178
- };
1179
- }
1180
- return { forms };
1181
- }
1182
- const pluralQuery = withComment({
1183
- pattern: `(
1184
- [
1185
- (jsx_element (jsx_opening_element name: (identifier) @name))
1186
- (jsx_self_closing_element name: (identifier) @name)
1187
- ] @call
1188
- (#eq? @name "Plural")
1189
- )`,
1190
- extract(match) {
1191
- const node = match.captures.find((c) => c.name === "call")?.node;
1192
- if (!node) return void 0;
1193
- let attrs = [];
1194
- if (node.type === "jsx_element") {
1195
- const open = node.childForFieldName("open_tag");
1196
- if (open) attrs = open.namedChildren;
1197
- } else if (node.type === "jsx_self_closing_element") attrs = node.namedChildren.slice(1);
1198
- let msgctxt;
1199
- let formsNode;
1200
- for (const child of attrs) {
1201
- if (child.type !== "jsx_attribute") continue;
1202
- const name = child.child(0);
1203
- const value = child.child(child.childCount - 1);
1204
- if (name?.text === "context" && value?.type === "string") msgctxt = value.text.slice(1, -1);
1205
- else if (name?.text === "forms" && value) formsNode = value;
1206
- }
1207
- if (!formsNode) return void 0;
1208
- const { forms, error } = parseForms(formsNode);
1209
- if (error) return {
1210
- node,
1211
- error
1212
- };
1213
- if (forms.length === 0) return void 0;
1214
- const translation = {
1215
- id: forms[0],
1216
- plural: forms[1],
1217
- message: forms
1218
- };
1219
- if (msgctxt) translation.context = msgctxt;
1220
- return {
1221
- node,
1222
- translation
1223
- };
1224
- }
1225
- });
1226
-
1227
- //#endregion
1228
- //#region src/plugins/react/queries/index.ts
1229
- const queries = [messageQuery, pluralQuery];
1230
-
1231
- //#endregion
1232
- //#region src/plugins/react/parse.ts
1233
- function parseSource(source, path$1) {
1234
- const context = { path: path$1 };
1235
- const { parser, language } = getParser(path$1);
1236
- const tree = parser.parse(source);
1237
- const translations = [];
1238
- const warnings = [];
1239
- const seen = /* @__PURE__ */ new Set();
1240
- for (const spec of queries) {
1241
- const query = getQuery(language, spec.pattern);
1242
- for (const match of query.matches(tree.rootNode)) {
1243
- const message = spec.extract(match);
1244
- if (!message) continue;
1245
- const { node, translation, error } = message;
1246
- if (seen.has(node.id)) continue;
1247
- seen.add(node.id);
1248
- const reference = getReference(node, context);
1249
- if (translation) translations.push({
1250
- ...translation,
1251
- comments: {
1252
- ...translation.comments,
1253
- reference
1254
- }
1255
- });
1256
- if (error) warnings.push({
1257
- error,
1258
- reference
1259
- });
1260
- }
1261
- }
1262
- return {
1263
- translations,
1264
- warnings
1265
- };
1266
- }
1267
-
1268
- //#endregion
1269
- //#region src/plugins/react/react.ts
1270
- const filter = /\.[cm]?[jt]sx$/;
1271
- function react() {
1272
- return {
1273
- name: "react",
1274
- setup(build) {
1275
- build.context.logger?.debug("react plugin initialized");
1276
- build.onResolve({
1277
- filter: /.*/,
1278
- namespace: "source"
1279
- }, ({ entrypoint, path: path$1, namespace: namespace$3 }) => {
1280
- return {
1281
- entrypoint,
1282
- namespace: namespace$3,
1283
- path: (0, node_path.resolve)(path$1)
1284
- };
1285
- });
1286
- build.onLoad({
1287
- filter,
1288
- namespace: "source"
1289
- }, async ({ entrypoint, path: path$1, namespace: namespace$3 }) => {
1290
- const data = await (0, node_fs_promises.readFile)(path$1, "utf8");
1291
- return {
1292
- entrypoint,
1293
- path: path$1,
1294
- namespace: namespace$3,
1295
- data
1296
- };
1297
- });
1298
- build.onProcess({
1299
- filter,
1300
- namespace: "source"
1301
- }, ({ entrypoint, path: path$1, data }) => {
1302
- const { translations, warnings } = parseSource(data, path$1);
1303
- for (const warning of warnings) build.context.logger?.warn(`${warning.error} at ${warning.reference}`);
1304
- build.resolve({
1305
- entrypoint,
1306
- path: path$1,
1307
- namespace: "translate",
1308
- data: translations
1309
- });
1310
- });
1311
- }
1312
- };
1313
- }
1314
-
1315
- //#endregion
1316
- exports.cleanup = cleanup;
1317
- exports.core = core;
1318
- exports.defineConfig = defineConfig;
1319
- exports.po = po;
1320
- exports.react = react;
1
+ const require_run = require('../run-BacOPd9p.cjs');
2
+ require('../static-CNiWpXhx.cjs');
3
+ const require_core = require('../core-CHb_Xdzl.cjs');
4
+
5
+ exports.cleanup = require_run.cleanup;
6
+ exports.core = require_run.core;
7
+ exports.defineConfig = require_core.defineConfig;
8
+ exports.po = require_run.po;
9
+ exports.react = require_run.react;
1321
10
  exports.run = require_run.run;