react-autolocale 0.1.0 → 0.3.0-beta.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 +248 -16
- package/dist/cli.js +800 -46
- package/dist/config-CYHyGpdX.js +21 -0
- package/dist/config.d.ts +56 -0
- package/dist/config.js +1 -0
- package/dist/index.d.ts +64 -3
- package/dist/index.js +154 -24
- package/dist/project-CGAWETvT.js +1400 -0
- package/dist/{redirect-CKNY4ru5.js → redirect-pDFblLdm.js} +5 -2
- package/dist/suggestion-CkZQqMvZ.js +24 -0
- package/dist/translate-COrJX1KS.d.ts +22 -0
- package/dist/vite.d.ts +12 -3
- package/dist/vite.js +82 -782
- package/package.json +22 -6
|
@@ -18,9 +18,12 @@ function redirectTarget(opts) {
|
|
|
18
18
|
return `/${target}${pathname}${opts.search ?? ""}${opts.hash ?? ""}`;
|
|
19
19
|
}
|
|
20
20
|
const STORAGE_KEY = "react-autolocale:language";
|
|
21
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* The same logic as a tiny inline script, so the root page redirects before anything paints. When the visitor stays,
|
|
23
|
+
* the URL is rewritten to the original language's prefix (no reload) so client-side routers see a prefixed path.
|
|
24
|
+
*/
|
|
22
25
|
function redirectScript(codes, original) {
|
|
23
|
-
return `(function(){try{var C=${JSON.stringify(codes)},O=${JSON.stringify(original)},p=location.pathname,m=/^\\/([a-z]{2,3})(?=\\/|$)/i.exec(p);if(m&&C.indexOf(m[1].toLowerCase())>-1)return;var t=null,s=localStorage.getItem(${JSON.stringify(STORAGE_KEY)});if(s&&C.indexOf(s)>-1)t=s;var l=navigator.languages||[navigator.language];for(var i=0;i<l.length&&!t;i++){var c=String(l[i]).toLowerCase();if(C.indexOf(c)>-1)t=c;else if(C.indexOf(c.split("-")[0])>-1)t=c.split("-")[0]}if(t&&t!==O)location.replace("/"+t+p+location.search+location.hash)}catch(e){}})()`;
|
|
26
|
+
return `(function(){try{var C=${JSON.stringify(codes)},O=${JSON.stringify(original)},p=location.pathname,m=/^\\/([a-z]{2,3})(?=\\/|$)/i.exec(p);if(m&&C.indexOf(m[1].toLowerCase())>-1)return;var t=null,s=localStorage.getItem(${JSON.stringify(STORAGE_KEY)});if(s&&C.indexOf(s)>-1)t=s;var l=navigator.languages||[navigator.language];for(var i=0;i<l.length&&!t;i++){var c=String(l[i]).toLowerCase();if(C.indexOf(c)>-1)t=c;else if(C.indexOf(c.split("-")[0])>-1)t=c.split("-")[0]}if(t&&t!==O)location.replace("/"+t+p+location.search+location.hash);else history.replaceState(history.state,"","/"+O+p+location.search+location.hash)}catch(e){}})()`;
|
|
24
27
|
}
|
|
25
28
|
//#endregion
|
|
26
29
|
export { redirectScript as n, redirectTarget as r, STORAGE_KEY as t };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/core/suggestion.ts
|
|
2
|
+
/**
|
|
3
|
+
* Should we offer the visitor another language? Looks at the first browser language we support:
|
|
4
|
+
* if it is the page's own language, was dismissed, or the visitor already chose a language, offer nothing.
|
|
5
|
+
*/
|
|
6
|
+
function suggestLanguage(opts) {
|
|
7
|
+
if (opts.chosen) return null;
|
|
8
|
+
for (const tag of opts.browser) {
|
|
9
|
+
const lower = String(tag).toLowerCase();
|
|
10
|
+
const base = lower.split("-")[0];
|
|
11
|
+
const code = opts.codes.includes(lower) ? lower : opts.codes.includes(base) ? base : null;
|
|
12
|
+
if (!code) continue;
|
|
13
|
+
return code === opts.current || opts.dismissed.includes(code) ? null : code;
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const DISMISSED_KEY = "react-autolocale:banner-dismissed";
|
|
18
|
+
const BANNER_EN = {
|
|
19
|
+
prompt: "This page is also available in {language}.",
|
|
20
|
+
switch: "Read in {language}",
|
|
21
|
+
dismiss: "Not now"
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
export { DISMISSED_KEY as n, suggestLanguage as r, BANNER_EN as t };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/core/translate.d.ts
|
|
2
|
+
interface Translator {
|
|
3
|
+
/** `contexts[i]` says where `texts[i]` appears ("button", "h1", "placeholder", ...). Engines may ignore it. */
|
|
4
|
+
translate(texts: string[], from: string, to: string, contexts?: string[]): Promise<string[]>;
|
|
5
|
+
}
|
|
6
|
+
/** The simplest way to plug in your own engine (DeepL, an LLM, ...): one function. */
|
|
7
|
+
type TranslateFn = (request: {
|
|
8
|
+
texts: string[];
|
|
9
|
+
contexts: string[];
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
}) => Promise<string[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Uses a local LLM through Ollama (free, runs on your machine). Unlike the default models it is told
|
|
15
|
+
* where each string appears, which fixes most one-word mistakes ("Home" in a nav bar is not "Sommaire").
|
|
16
|
+
*/
|
|
17
|
+
declare function ollama(options?: {
|
|
18
|
+
model: string;
|
|
19
|
+
url?: string;
|
|
20
|
+
}): Translator;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { Translator as n, ollama as r, TranslateFn as t };
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,16 +1,25 @@
|
|
|
1
|
+
import { n as Translator, r as ollama, t as TranslateFn } from "./translate-COrJX1KS.js";
|
|
1
2
|
import { Plugin } from "vite";
|
|
2
3
|
//#region src/vite/index.d.ts
|
|
3
4
|
export interface ReactAutolocaleOptions {
|
|
4
|
-
/** Folders (relative to the project root) scanned for JSX.
|
|
5
|
+
/** Folders (relative to the project root) scanned for JSX. Prefer `include` in auto-locale.config.ts, which the CLI also reads. */
|
|
5
6
|
include?: string[];
|
|
6
|
-
/** Fix individual translations
|
|
7
|
+
/** Fix individual translations in code, e.g. { fr: { Contact: "Contact" } }. Adds to (and wins over) react-autolocale.overrides.json. */
|
|
7
8
|
overrides?: Record<string, Record<string, string>>;
|
|
8
9
|
/**
|
|
9
10
|
* Extra pages to build, mainly dynamic ones such as "/users/1" (a function can fetch them). Pages reached
|
|
10
11
|
* by links and fixed routes written in your router (<Route path="/thank-you">) are found automatically.
|
|
11
12
|
*/
|
|
12
13
|
routes?: string[] | (() => string[] | Promise<string[]>);
|
|
14
|
+
/** @deprecated Builds no longer translate. Set `provider` in auto-locale.config.ts; `react-autolocale translate` uses it. */
|
|
15
|
+
engine?: Translator | TranslateFn;
|
|
16
|
+
/** @deprecated Builds no longer translate. Set `glossary` in auto-locale.config.ts. */
|
|
17
|
+
glossary?: Record<string, Record<string, string>>;
|
|
13
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Reads the generated catalogs and serves them to the runtime. It never translates, downloads a model or calls
|
|
21
|
+
* a translation API: missing translations show the source text, and `react-autolocale sync` fills them.
|
|
22
|
+
*/
|
|
14
23
|
export default function reactAutolocale(options?: ReactAutolocaleOptions): Plugin;
|
|
15
24
|
//#endregion
|
|
16
|
-
export { reactAutolocale };
|
|
25
|
+
export { type TranslateFn, type Translator, reactAutolocale, ollama };
|