react-autolocale 0.4.0 → 0.5.0
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/README.md +36 -6
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +13 -1
- package/dist/index.js +47 -4
- package/dist/{project-4C7cUxzd.js → project-DcYRIvym.js} +952 -92
- package/dist/vite.js +34 -6
- package/package.json +3 -2
package/dist/vite.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as redirectScript } from "./redirect-pDFblLdm.js";
|
|
2
|
-
import { A as
|
|
3
|
-
import path from "node:path";
|
|
2
|
+
import { A as walk, B as getLanguage, C as isContentJson, D as parserPlugins, E as buildFactsIndex, M as messageId, O as transformJsx, P as readBanner, R as ollama, T as FactsIndex, _ as loadDicts, d as OVERRIDES_FILE, j as translateHead, k as isSourceFile, m as readOverrides, p as mergeOverrides, r as loadProject, w as jsonModule } from "./project-DcYRIvym.js";
|
|
4
3
|
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
5
|
import { JSDOM, VirtualConsole } from "jsdom";
|
|
6
6
|
import { parse } from "@babel/parser";
|
|
7
7
|
import _traverse from "@babel/traverse";
|
|
@@ -377,6 +377,7 @@ async function prerender(opts) {
|
|
|
377
377
|
}
|
|
378
378
|
//#endregion
|
|
379
379
|
//#region src/vite/index.ts
|
|
380
|
+
const JSON_PREFIX = "\0autolocale-json:";
|
|
380
381
|
const VIRTUAL_ID = "virtual:react-autolocale";
|
|
381
382
|
const RESOLVED_ID = "\0" + VIRTUAL_ID;
|
|
382
383
|
/** One module per language, so each dictionary is fetched only when that language is used. */
|
|
@@ -397,14 +398,17 @@ function reactAutolocale(options = {}) {
|
|
|
397
398
|
usedLegacy: false
|
|
398
399
|
};
|
|
399
400
|
let banner = {};
|
|
401
|
+
let factsIndex = new FactsIndex();
|
|
400
402
|
let server;
|
|
401
403
|
let rendered = false;
|
|
404
|
+
let bundleWritten = false;
|
|
402
405
|
const log = (msg) => console.log(msg);
|
|
403
406
|
const warn = (msg) => config?.logger ? config.logger.warn(`[react-autolocale] ${msg}`) : log(`[react-autolocale] ${msg}`);
|
|
404
407
|
async function refresh() {
|
|
405
408
|
project = await loadProject(root, { log });
|
|
406
409
|
if (options.include) project.include = options.include;
|
|
407
410
|
includeDirs = project.include.map((d) => path.resolve(root, d) + path.sep);
|
|
411
|
+
factsIndex = buildFactsIndex(root, project.include);
|
|
408
412
|
dicts = loadDicts(project, mergeOverrides(readOverrides(root), options.overrides));
|
|
409
413
|
banner = readBanner(project.output, root);
|
|
410
414
|
}
|
|
@@ -424,13 +428,15 @@ function reactAutolocale(options = {}) {
|
|
|
424
428
|
rtl: !!getLanguage(code)?.rtl
|
|
425
429
|
}));
|
|
426
430
|
const loaders = site.languages.map((code) => `${JSON.stringify(code)}: () => import(${JSON.stringify(DICT_PREFIX + code)})`);
|
|
431
|
+
const eager = config.command === "serve" ? Object.fromEntries(site.languages.map((code) => [code, dicts.byId[code] ?? {}])) : {};
|
|
427
432
|
return [
|
|
428
433
|
`export const original = ${JSON.stringify(site.original)};`,
|
|
429
434
|
`export const originalNative = ${JSON.stringify(getLanguage(site.original)?.native ?? site.original)};`,
|
|
430
435
|
`export const seo = ${JSON.stringify(site.seo)};`,
|
|
431
436
|
`export const banner = ${JSON.stringify(banner)};`,
|
|
432
437
|
`export const languages = ${JSON.stringify(meta)};`,
|
|
433
|
-
`export const loaders = { ${loaders.join(", ")} }
|
|
438
|
+
`export const loaders = { ${loaders.join(", ")} };`,
|
|
439
|
+
`export const eager = ${JSON.stringify(eager)};`
|
|
434
440
|
].join("\n");
|
|
435
441
|
}
|
|
436
442
|
let timer;
|
|
@@ -492,12 +498,29 @@ function reactAutolocale(options = {}) {
|
|
|
492
498
|
if (server) server.watcher.add(project.output);
|
|
493
499
|
report();
|
|
494
500
|
},
|
|
495
|
-
resolveId(id) {
|
|
501
|
+
async resolveId(id, importer, options) {
|
|
496
502
|
if (id === VIRTUAL_ID) return RESOLVED_ID;
|
|
497
503
|
if (id.startsWith(DICT_PREFIX)) return "\0" + id;
|
|
504
|
+
if (project && importer && /\.json$/.test(id) && !importer.startsWith("\0")) {
|
|
505
|
+
const from = importer.split("?")[0];
|
|
506
|
+
if (!includeDirs.some((d) => from.startsWith(d))) return null;
|
|
507
|
+
const resolved = await this.resolve(id, importer, {
|
|
508
|
+
...options,
|
|
509
|
+
skipSelf: true
|
|
510
|
+
});
|
|
511
|
+
if (!resolved || resolved.external || resolved.id.includes("?")) return null;
|
|
512
|
+
if (!includeDirs.some((d) => resolved.id.startsWith(d)) || !isContentJson(resolved.id, [project.output, project.meta])) return null;
|
|
513
|
+
if (jsonModule(fs.readFileSync(resolved.id, "utf8"), factsIndex.facts()) === null) return null;
|
|
514
|
+
return JSON_PREFIX + resolved.id + ".js";
|
|
515
|
+
}
|
|
498
516
|
return null;
|
|
499
517
|
},
|
|
500
518
|
load(id) {
|
|
519
|
+
if (id.startsWith(JSON_PREFIX)) {
|
|
520
|
+
const file = id.slice(17, -3);
|
|
521
|
+
this.addWatchFile(file);
|
|
522
|
+
return jsonModule(fs.readFileSync(file, "utf8"), factsIndex.facts());
|
|
523
|
+
}
|
|
501
524
|
if (id === RESOLVED_ID) return virtualModule();
|
|
502
525
|
if (id.startsWith("\0" + DICT_PREFIX)) {
|
|
503
526
|
const lang = id.slice(31);
|
|
@@ -509,7 +532,9 @@ function reactAutolocale(options = {}) {
|
|
|
509
532
|
const file = id.split("?")[0];
|
|
510
533
|
if (file.startsWith("\0") || file.includes("node_modules") || !isSourceFile(file)) return null;
|
|
511
534
|
if (!includeDirs.some((d) => file.startsWith(d))) return null;
|
|
512
|
-
|
|
535
|
+
if (project && (file.startsWith(project.output + path.sep) || file.startsWith(project.meta + path.sep))) return null;
|
|
536
|
+
factsIndex.set(file, code);
|
|
537
|
+
const result = transformJsx(code, file, { facts: factsIndex.facts() });
|
|
513
538
|
if (!result) return null;
|
|
514
539
|
if (config.command === "serve" && project) noteUntranslated(result.strings);
|
|
515
540
|
return {
|
|
@@ -517,10 +542,13 @@ function reactAutolocale(options = {}) {
|
|
|
517
542
|
map: result.map
|
|
518
543
|
};
|
|
519
544
|
},
|
|
545
|
+
writeBundle() {
|
|
546
|
+
bundleWritten = true;
|
|
547
|
+
},
|
|
520
548
|
closeBundle: {
|
|
521
549
|
order: "post",
|
|
522
550
|
async handler() {
|
|
523
|
-
if (config.command !== "build" || config.build.ssr || rendered) return;
|
|
551
|
+
if (config.command !== "build" || config.build.ssr || rendered || !bundleWritten) return;
|
|
524
552
|
rendered = true;
|
|
525
553
|
const extra = typeof options.routes === "function" ? await options.routes() : options.routes ?? [];
|
|
526
554
|
const routes = [.../* @__PURE__ */ new Set([...discoverRoutes(root, project.include), ...extra])];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-autolocale",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Wrap your React + Vite app in <AutoScale> and get fully translated static pages (/fr, /es, ...). Translations are generated by an explicit CLI step with a local model, OpenAI or Anthropic; builds never translate.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"test": "vitest run",
|
|
41
41
|
"typecheck": "tsc -p .",
|
|
42
42
|
"prepublishOnly": "pnpm build && pnpm test",
|
|
43
|
-
"e2e": "node e2e/run.mjs"
|
|
43
|
+
"e2e": "node e2e/run.mjs",
|
|
44
|
+
"e2e:patterns": "node e2e/patterns.mjs"
|
|
44
45
|
},
|
|
45
46
|
"engines": {
|
|
46
47
|
"node": ">=20"
|