wuchale 0.3.1 → 0.4.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 +12 -8
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/preprocess/compile.d.ts +4 -0
- package/dist/preprocess/compile.js +50 -0
- package/dist/preprocess/compile.js.map +1 -0
- package/dist/preprocess/gemini.d.ts +4 -0
- package/{preprocess → dist/preprocess}/gemini.js +26 -37
- package/dist/preprocess/gemini.js.map +1 -0
- package/dist/preprocess/index.d.ts +50 -0
- package/{preprocess → dist/preprocess}/index.js +108 -135
- package/dist/preprocess/index.js.map +1 -0
- package/dist/preprocess/prep.d.ts +89 -0
- package/dist/preprocess/prep.js +560 -0
- package/dist/preprocess/prep.js.map +1 -0
- package/dist/runtime.svelte.d.ts +5 -0
- package/dist/runtime.svelte.js +32 -0
- package/dist/runtime.svelte.js.map +1 -0
- package/package.json +18 -6
- package/runtime.svelte +1 -47
- package/index.js +0 -3
- package/preprocess/compile.js +0 -52
- package/preprocess/prep.js +0 -652
package/README.md
CHANGED
|
@@ -97,19 +97,24 @@ export default {
|
|
|
97
97
|
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
Create `/locales/` if it doesn't exist, and
|
|
101
|
-
component. Assuming `/src/App.svelte`:
|
|
100
|
+
Create `/src/locales/` (relative to the projects root) if it doesn't exist, and
|
|
101
|
+
then set it up in your main component. Assuming `/src/App.svelte`:
|
|
102
102
|
|
|
103
103
|
```svelte
|
|
104
104
|
<script>
|
|
105
|
-
import {setTranslations} from 'wuchale/runtime.svelte'
|
|
105
|
+
import {setTranslations} from 'wuchale/runtime.svelte.js'
|
|
106
106
|
|
|
107
107
|
let locale = $state('en')
|
|
108
108
|
|
|
109
109
|
$effect.pre(() => {
|
|
110
|
-
|
|
110
|
+
// IMPORTANT! The path should be relative to the current file (vite restriction).
|
|
111
|
+
// for the default sveltekit template for example, it's `../locales/${locale}.json`
|
|
112
|
+
// because the default main component is located at /src/routes/+page.svelte
|
|
113
|
+
import(`./locales/${locale}.json`).then(mod => {
|
|
111
114
|
setTranslations(mod.default)
|
|
112
115
|
})
|
|
116
|
+
// but this only applies if you want to do lazy loading.
|
|
117
|
+
// Otherwise you can do an absolute import
|
|
113
118
|
})
|
|
114
119
|
</script>
|
|
115
120
|
```
|
|
@@ -287,9 +292,9 @@ This includes all JS/TS code that is:
|
|
|
287
292
|
The rule for this is that all strings and template strings that start with
|
|
288
293
|
capital letters are extracted. Additionally, if they are used inside the
|
|
289
294
|
`<script>` tags and in their own files (third case above), there is the
|
|
290
|
-
additional restriction that they must be inside a `$derived`
|
|
291
|
-
declaration. This is to make the behavior less magic and being more
|
|
292
|
-
Example:
|
|
295
|
+
additional restriction that they must be inside a `$derived` or `$derived.by`
|
|
296
|
+
variable declaration. This is to make the behavior less magic and being more
|
|
297
|
+
explicit. Example:
|
|
293
298
|
|
|
294
299
|
```svelte
|
|
295
300
|
<script>
|
|
@@ -348,7 +353,6 @@ export const defaultOptions = {
|
|
|
348
353
|
sourceLocale: 'en',
|
|
349
354
|
otherLocales: ['am'],
|
|
350
355
|
localesDir: './locales',
|
|
351
|
-
importFrom: 'wuchale/runtime.svelte',
|
|
352
356
|
heuristic: defaultHeuristic,
|
|
353
357
|
geminiAPIKey: 'env',
|
|
354
358
|
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,uBAAuB,CAAA;AAE1C,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// $$ cd .. && npm run test
|
|
2
|
+
import { parse } from "svelte/compiler";
|
|
3
|
+
function walkCompileNodes(node) {
|
|
4
|
+
if (node.type === 'Text') {
|
|
5
|
+
return [node.data];
|
|
6
|
+
}
|
|
7
|
+
if (node.type === 'Literal') {
|
|
8
|
+
if (typeof node.value === 'number') {
|
|
9
|
+
return [node.value];
|
|
10
|
+
}
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
if (node.type === 'ExpressionTag') {
|
|
14
|
+
return walkCompileNodes(node.expression);
|
|
15
|
+
}
|
|
16
|
+
if (node.type === 'Component') {
|
|
17
|
+
return [[
|
|
18
|
+
Number(node.name.slice(1)),
|
|
19
|
+
...walkCompileNodes(node.fragment),
|
|
20
|
+
]];
|
|
21
|
+
}
|
|
22
|
+
if (node.type === 'Fragment') {
|
|
23
|
+
const parts = [];
|
|
24
|
+
for (const child of node.nodes) {
|
|
25
|
+
parts.push(...walkCompileNodes(child));
|
|
26
|
+
}
|
|
27
|
+
return parts;
|
|
28
|
+
}
|
|
29
|
+
console.error('Unexpected node type', node);
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
export default function compileTranslation(text, fallback) {
|
|
33
|
+
if (!text) {
|
|
34
|
+
return fallback;
|
|
35
|
+
}
|
|
36
|
+
if (!text.includes('<') && !text.includes('{')) {
|
|
37
|
+
return text;
|
|
38
|
+
}
|
|
39
|
+
// <0></0> to <X0></X0> to please svelte parser
|
|
40
|
+
text = text.replace(/(<|(<\/))(\d+)/g, '$1X$3');
|
|
41
|
+
try {
|
|
42
|
+
const ast = parse(text, { modern: true });
|
|
43
|
+
return walkCompileNodes(ast.fragment);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error(err);
|
|
47
|
+
return fallback;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/preprocess/compile.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAE3B,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAOvC,SAAS,gBAAgB,CAAC,IAAgG;IACtH,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,EAAE,CAAA;IACb,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAChC,OAAO,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC5C,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC5B,OAAO,CAAC;gBACJ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC1B,GAAG,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;aACrC,CAAC,CAAA;IACN,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,EAAE,CAAA;QAChB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAA;QAC1C,CAAC;QACD,OAAO,KAAK,CAAA;IAChB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAA;IAC3C,OAAO,EAAE,CAAA;AACb,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,IAAY,EAAE,QAA0B;IAC/E,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,QAAQ,CAAA;IACnB,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAA;IACf,CAAC;IACD,+CAA+C;IAC/C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;IAC/C,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QACzC,OAAO,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAClB,OAAO,QAAQ,CAAA;IACnB,CAAC;AACL,CAAC"}
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
// $$ cd .. && npm run test
|
|
2
2
|
// $$ node %f
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @param {import('pofile').Item[]} fragments
|
|
11
|
-
* @param {string} sourceLocale
|
|
12
|
-
* @param {string} targetLocale
|
|
13
|
-
*/
|
|
3
|
+
import PO from 'pofile';
|
|
4
|
+
const baseURL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=';
|
|
5
|
+
const h = { 'Content-Type': 'application/json' };
|
|
6
|
+
function codeStandard(locale) {
|
|
7
|
+
return `ISO 639-${locale.length === 2 ? 1 : 3}`;
|
|
8
|
+
}
|
|
14
9
|
function prepareData(fragments, sourceLocale, targetLocale) {
|
|
15
10
|
const instruction = `
|
|
16
11
|
You will be given the contents of a gettext .po file for a web app.
|
|
17
12
|
Translate each of the items from the source to the target language.
|
|
18
|
-
|
|
19
|
-
The
|
|
20
|
-
The target language is: ${targetLocale}.
|
|
13
|
+
The source language ${codeStandard(sourceLocale)} code is: ${sourceLocale}.
|
|
14
|
+
The target language ${codeStandard(targetLocale)} code is: ${targetLocale}.
|
|
21
15
|
You can read all of the information for the items including contexts,
|
|
22
16
|
comments and references to get the appropriate context about each item.
|
|
23
17
|
Provide the translated fragments in the in the same order, preserving
|
|
@@ -27,40 +21,35 @@ function prepareData(fragments, sourceLocale, targetLocale) {
|
|
|
27
21
|
- <0>something</0>: means something enclosed in some tags, like HTML tags
|
|
28
22
|
- <0/>: means a self closing tag, like in HTML
|
|
29
23
|
In all of the examples, 0 is an example for any integer.
|
|
30
|
-
|
|
31
|
-
const po = new PO()
|
|
32
|
-
po.items = fragments
|
|
24
|
+
`;
|
|
25
|
+
const po = new PO();
|
|
26
|
+
po.items = fragments;
|
|
33
27
|
return {
|
|
34
28
|
system_instruction: {
|
|
35
29
|
parts: [{ text: instruction }]
|
|
36
30
|
},
|
|
37
|
-
contents: [{parts: [{text: po.toString()}]}]
|
|
38
|
-
}
|
|
31
|
+
contents: [{ parts: [{ text: po.toString() }] }]
|
|
32
|
+
};
|
|
39
33
|
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* @param {string} targetLocale
|
|
43
|
-
* @param {string | undefined} apiKey
|
|
44
|
-
*/
|
|
45
|
-
function setupGemini(sourceLocale = 'en', targetLocale, apiKey) {
|
|
34
|
+
function setupGemini(sourceLocale, targetLocale, apiKey) {
|
|
46
35
|
if (apiKey === 'env') {
|
|
47
|
-
apiKey = process.env.GEMINI_API_KEY
|
|
36
|
+
apiKey = process.env.GEMINI_API_KEY;
|
|
48
37
|
}
|
|
49
38
|
if (!apiKey) {
|
|
50
|
-
return
|
|
39
|
+
return;
|
|
51
40
|
}
|
|
52
|
-
const url = `${baseURL}${apiKey}
|
|
53
|
-
return async (
|
|
54
|
-
const data = prepareData(fragments, sourceLocale, targetLocale)
|
|
55
|
-
const res = await fetch(url, {method: 'POST', headers: h, body: JSON.stringify(data)})
|
|
56
|
-
const json = await res.json()
|
|
57
|
-
const resText = json.candidates[0]
|
|
41
|
+
const url = `${baseURL}${apiKey}`;
|
|
42
|
+
return async (fragments) => {
|
|
43
|
+
const data = prepareData(fragments, sourceLocale, targetLocale);
|
|
44
|
+
const res = await fetch(url, { method: 'POST', headers: h, body: JSON.stringify(data) });
|
|
45
|
+
const json = await res.json();
|
|
46
|
+
const resText = json.candidates[0]?.content.parts[0].text;
|
|
58
47
|
for (const [i, item] of PO.parse(resText).items.entries()) {
|
|
59
48
|
if (item.msgstr[0]) {
|
|
60
|
-
fragments[i].msgstr = item.msgstr
|
|
49
|
+
fragments[i].msgstr = item.msgstr;
|
|
61
50
|
}
|
|
62
51
|
}
|
|
63
|
-
}
|
|
52
|
+
};
|
|
64
53
|
}
|
|
65
|
-
|
|
66
|
-
|
|
54
|
+
export default setupGemini;
|
|
55
|
+
//# sourceMappingURL=gemini.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/preprocess/gemini.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,aAAa;AAEb,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEvB,MAAM,OAAO,GAAG,+FAA+F,CAAA;AAC/G,MAAM,CAAC,GAAG,EAAC,cAAc,EAAE,kBAAkB,EAAC,CAAA;AAE9C,SAAS,YAAY,CAAC,MAAc;IAChC,OAAO,WAAW,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACnD,CAAC;AAID,SAAS,WAAW,CAAC,SAAqB,EAAE,YAAoB,EAAE,YAAoB;IAClF,MAAM,WAAW,GAAG;;;8BAGM,YAAY,CAAC,YAAY,CAAC,aAAa,YAAY;8BACnD,YAAY,CAAC,YAAY,CAAC,aAAa,YAAY;;;;;;;;;;KAU5E,CAAA;IACD,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,CAAA;IACnB,EAAE,CAAC,KAAK,GAAG,SAAS,CAAA;IACpB,OAAO;QACH,kBAAkB,EAAE;YAChB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;SACjC;QACD,QAAQ,EAAE,CAAC,EAAC,KAAK,EAAE,CAAC,EAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAC,CAAC,EAAC,CAAC;KAC/C,CAAA;AACL,CAAC;AAUD,SAAS,WAAW,CAAC,YAAoB,EAAE,YAAoB,EAAE,MAAqB;IAClF,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACnB,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IACvC,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAM;IACV,CAAC;IACD,MAAM,GAAG,GAAG,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;IACjC,OAAO,KAAK,EAAE,SAAqB,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,CAAA;QAC/D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAC,CAAC,CAAA;QACtF,MAAM,IAAI,GAAc,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACzD,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YACxD,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjB,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;YACrC,CAAC;QACL,CAAC;IACL,CAAC,CAAA;AACL,CAAC;AAED,eAAe,WAAW,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { defaultHeuristic } from "./prep.js";
|
|
2
|
+
import { type AST } from "svelte/compiler";
|
|
3
|
+
import { type CompiledFragment } from "./compile.js";
|
|
4
|
+
import type { Program } from 'estree';
|
|
5
|
+
export declare const defaultOptions: {
|
|
6
|
+
sourceLocale: string;
|
|
7
|
+
otherLocales: string[];
|
|
8
|
+
localesDir: string;
|
|
9
|
+
heuristic: typeof defaultHeuristic;
|
|
10
|
+
geminiAPIKey: string;
|
|
11
|
+
};
|
|
12
|
+
export default function wuchale(options?: {
|
|
13
|
+
sourceLocale: string;
|
|
14
|
+
otherLocales: string[];
|
|
15
|
+
localesDir: string;
|
|
16
|
+
heuristic: typeof defaultHeuristic;
|
|
17
|
+
geminiAPIKey: string;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
name: string;
|
|
20
|
+
configResolved(config: {
|
|
21
|
+
env: {
|
|
22
|
+
PROD: boolean;
|
|
23
|
+
};
|
|
24
|
+
root: string;
|
|
25
|
+
}): Promise<void>;
|
|
26
|
+
transform: {
|
|
27
|
+
order: string;
|
|
28
|
+
handler: (code: string, id: string) => Promise<{
|
|
29
|
+
code?: undefined;
|
|
30
|
+
map?: undefined;
|
|
31
|
+
} | {
|
|
32
|
+
code: string;
|
|
33
|
+
map: import("magic-string").SourceMap;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
buildEnd(): Promise<void>;
|
|
37
|
+
setupTesting(): {
|
|
38
|
+
translations: {};
|
|
39
|
+
compiled: {
|
|
40
|
+
[locale: string]: CompiledFragment[];
|
|
41
|
+
};
|
|
42
|
+
preprocess: (content: string, ast: AST.Root | Program, filename: string) => Promise<{
|
|
43
|
+
code?: undefined;
|
|
44
|
+
map?: undefined;
|
|
45
|
+
} | {
|
|
46
|
+
code: string;
|
|
47
|
+
map: import("magic-string").SourceMap;
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
50
|
+
}>;
|
|
@@ -1,249 +1,222 @@
|
|
|
1
|
-
import Preprocess, { defaultHeuristic, IndexTracker, NestText } from "./prep.js"
|
|
2
|
-
import { parse } from "svelte/compiler"
|
|
3
|
-
import {writeFile} from 'node:fs/promises'
|
|
4
|
-
import compileTranslation from "./compile.js"
|
|
5
|
-
import setupGemini from "./gemini.js"
|
|
6
|
-
import PO from "pofile"
|
|
7
|
-
import { normalize, relative } from "node:path"
|
|
8
|
-
|
|
1
|
+
import Preprocess, { defaultHeuristic, IndexTracker, NestText } from "./prep.js";
|
|
2
|
+
import { parse } from "svelte/compiler";
|
|
3
|
+
import { writeFile } from 'node:fs/promises';
|
|
4
|
+
import compileTranslation, {} from "./compile.js";
|
|
5
|
+
import setupGemini, {} from "./gemini.js";
|
|
6
|
+
import PO from "pofile";
|
|
7
|
+
import { normalize, relative } from "node:path";
|
|
9
8
|
export const defaultOptions = {
|
|
10
9
|
sourceLocale: 'en',
|
|
11
10
|
otherLocales: ['am'],
|
|
12
|
-
localesDir: './locales',
|
|
13
|
-
importFrom: 'wuchale/runtime.svelte',
|
|
11
|
+
localesDir: './src/locales',
|
|
14
12
|
heuristic: defaultHeuristic,
|
|
15
13
|
geminiAPIKey: 'env',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @param {string} filename
|
|
20
|
-
*/
|
|
14
|
+
};
|
|
21
15
|
async function loadPONoFail(filename) {
|
|
22
16
|
return new Promise((res) => {
|
|
23
17
|
PO.load(filename, (err, po) => {
|
|
24
|
-
const translations = {}
|
|
25
|
-
let total = 0
|
|
26
|
-
let obsolete = 0
|
|
27
|
-
let untranslated = 0
|
|
18
|
+
const translations = {};
|
|
19
|
+
let total = 0;
|
|
20
|
+
let obsolete = 0;
|
|
21
|
+
let untranslated = 0;
|
|
28
22
|
if (!err) {
|
|
29
23
|
for (const item of po.items) {
|
|
30
|
-
total
|
|
24
|
+
total++;
|
|
31
25
|
if (item.obsolete) {
|
|
32
|
-
obsolete
|
|
33
|
-
continue
|
|
26
|
+
obsolete++;
|
|
27
|
+
continue;
|
|
34
28
|
}
|
|
35
29
|
if (!item.msgstr[0]) {
|
|
36
|
-
untranslated
|
|
30
|
+
untranslated++;
|
|
37
31
|
}
|
|
38
|
-
const nTxt = new NestText(item.msgid, null, item.msgctxt)
|
|
39
|
-
translations[nTxt.toKey()] = item
|
|
32
|
+
const nTxt = new NestText(item.msgid, null, item.msgctxt);
|
|
33
|
+
translations[nTxt.toKey()] = item;
|
|
40
34
|
}
|
|
41
35
|
}
|
|
42
|
-
res({translations, total, obsolete, untranslated})
|
|
43
|
-
})
|
|
44
|
-
})
|
|
36
|
+
res({ translations, total, obsolete, untranslated });
|
|
37
|
+
});
|
|
38
|
+
});
|
|
45
39
|
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @param {{ [s: string]: any; } | ArrayLike<any>} translations
|
|
49
|
-
* @param {string} filename
|
|
50
|
-
*/
|
|
51
40
|
async function savePO(translations, filename) {
|
|
52
|
-
const po = new PO()
|
|
41
|
+
const po = new PO();
|
|
53
42
|
for (const item of Object.values(translations)) {
|
|
54
|
-
po.items.push(item)
|
|
43
|
+
po.items.push(item);
|
|
55
44
|
}
|
|
56
45
|
return new Promise((res, rej) => {
|
|
57
46
|
po.save(filename, err => {
|
|
58
47
|
if (err) {
|
|
59
|
-
rej(err)
|
|
60
|
-
}
|
|
61
|
-
|
|
48
|
+
rej(err);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
res(null);
|
|
62
52
|
}
|
|
63
|
-
})
|
|
64
|
-
})
|
|
53
|
+
});
|
|
54
|
+
});
|
|
65
55
|
}
|
|
66
|
-
|
|
67
56
|
function mergeOptionsWithDefault(options = defaultOptions) {
|
|
68
57
|
for (const key of Object.keys(defaultOptions)) {
|
|
69
58
|
if (key in options) {
|
|
70
|
-
continue
|
|
59
|
+
continue;
|
|
71
60
|
}
|
|
72
|
-
options[key] = defaultOptions[key]
|
|
61
|
+
options[key] = defaultOptions[key];
|
|
73
62
|
}
|
|
74
63
|
}
|
|
75
|
-
|
|
76
64
|
export default async function wuchale(options = defaultOptions) {
|
|
77
|
-
mergeOptionsWithDefault(options)
|
|
78
|
-
const locales = [options.sourceLocale, ...options.otherLocales]
|
|
79
|
-
const translations = {}
|
|
80
|
-
const compiledFname = {}
|
|
81
|
-
const translationsFname = {}
|
|
65
|
+
mergeOptionsWithDefault(options);
|
|
66
|
+
const locales = [options.sourceLocale, ...options.otherLocales];
|
|
67
|
+
const translations = {};
|
|
68
|
+
const compiledFname = {};
|
|
69
|
+
const translationsFname = {};
|
|
82
70
|
for (const loc of locales) {
|
|
83
|
-
compiledFname[loc] = `${options.localesDir}/${loc}.json
|
|
84
|
-
translationsFname[loc] = `${options.localesDir}/${loc}.po
|
|
71
|
+
compiledFname[loc] = `${options.localesDir}/${loc}.json`;
|
|
72
|
+
translationsFname[loc] = `${options.localesDir}/${loc}.po`;
|
|
85
73
|
}
|
|
86
|
-
|
|
87
|
-
let
|
|
88
|
-
let
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
let indexTracker = new IndexTracker({})
|
|
92
|
-
|
|
93
|
-
const compiled = {}
|
|
94
|
-
|
|
74
|
+
let forProduction = false;
|
|
75
|
+
let projectRoot = '';
|
|
76
|
+
let sourceTranslations = {};
|
|
77
|
+
let indexTracker = new IndexTracker({});
|
|
78
|
+
const compiled = {};
|
|
95
79
|
async function loadFilesAndSetup() {
|
|
96
80
|
for (const loc of locales) {
|
|
97
|
-
const {translations: trans, total, obsolete, untranslated} = await loadPONoFail(translationsFname[loc])
|
|
98
|
-
translations[loc] = trans
|
|
99
|
-
console.info(`i18n stats (${loc}): total: ${total}, obsolete: ${obsolete}, untranslated: ${untranslated}`)
|
|
81
|
+
const { translations: trans, total, obsolete, untranslated } = await loadPONoFail(translationsFname[loc]);
|
|
82
|
+
translations[loc] = trans;
|
|
83
|
+
console.info(`i18n stats (${loc}): total: ${total}, obsolete: ${obsolete}, untranslated: ${untranslated}`);
|
|
100
84
|
}
|
|
101
|
-
sourceTranslations = translations[options.sourceLocale]
|
|
102
|
-
indexTracker = new IndexTracker(sourceTranslations)
|
|
85
|
+
sourceTranslations = translations[options.sourceLocale];
|
|
86
|
+
indexTracker = new IndexTracker(sourceTranslations);
|
|
103
87
|
// startup compile
|
|
104
88
|
for (const loc of locales) {
|
|
105
|
-
compiled[loc] = []
|
|
89
|
+
compiled[loc] = [];
|
|
106
90
|
for (const key in translations[loc]) {
|
|
107
|
-
const poItem = translations[loc][key]
|
|
91
|
+
const poItem = translations[loc][key];
|
|
108
92
|
if (forProduction) {
|
|
109
|
-
poItem.references = []
|
|
93
|
+
poItem.references = [];
|
|
110
94
|
}
|
|
111
|
-
const index = indexTracker.get(key)
|
|
112
|
-
compiled[loc][index] = compileTranslation(poItem.msgstr[0], compiled[options.sourceLocale][index])
|
|
95
|
+
const index = indexTracker.get(key);
|
|
96
|
+
compiled[loc][index] = compileTranslation(poItem.msgstr[0], compiled[options.sourceLocale][index]);
|
|
113
97
|
}
|
|
114
|
-
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc], null, 2))
|
|
98
|
+
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc], null, 2));
|
|
115
99
|
}
|
|
116
100
|
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* @param {string} content
|
|
120
|
-
* @param {import('estree').Program | import("svelte/compiler").AST.Root} ast
|
|
121
|
-
* @param {string} filename
|
|
122
|
-
*/
|
|
123
101
|
async function preprocess(content, ast, filename) {
|
|
124
|
-
const prep = new Preprocess(indexTracker, options.heuristic
|
|
125
|
-
const txts = prep.process(content, ast)
|
|
102
|
+
const prep = new Preprocess(indexTracker, options.heuristic);
|
|
103
|
+
const txts = prep.process(content, ast);
|
|
126
104
|
if (!txts.length) {
|
|
127
|
-
return {}
|
|
105
|
+
return {};
|
|
128
106
|
}
|
|
129
107
|
for (const loc of locales) {
|
|
130
|
-
const newTxts = []
|
|
108
|
+
const newTxts = [];
|
|
131
109
|
for (const nTxt of txts) {
|
|
132
|
-
let key = nTxt.toKey()
|
|
133
|
-
let translated = translations[loc][key]
|
|
110
|
+
let key = nTxt.toKey();
|
|
111
|
+
let translated = translations[loc][key];
|
|
134
112
|
if (translated == null) {
|
|
135
|
-
translated = new PO.Item()
|
|
136
|
-
translated.msgid = nTxt.toString()
|
|
137
|
-
translations[loc][key] = translated
|
|
113
|
+
translated = new PO.Item();
|
|
114
|
+
translated.msgid = nTxt.toString();
|
|
115
|
+
translations[loc][key] = translated;
|
|
138
116
|
}
|
|
139
117
|
if (nTxt.context) {
|
|
140
|
-
translated.msgctxt = nTxt.context
|
|
118
|
+
translated.msgctxt = nTxt.context;
|
|
141
119
|
}
|
|
142
120
|
if (!translated.references.includes(filename)) {
|
|
143
|
-
translated.references.push(filename)
|
|
121
|
+
translated.references.push(filename);
|
|
144
122
|
}
|
|
145
123
|
if (loc === options.sourceLocale) {
|
|
146
|
-
const txt = nTxt.toString()
|
|
124
|
+
const txt = nTxt.toString();
|
|
147
125
|
if (translated.msgstr[0] !== txt) {
|
|
148
|
-
translated.msgstr = [txt]
|
|
149
|
-
newTxts.push(translated)
|
|
126
|
+
translated.msgstr = [txt];
|
|
127
|
+
newTxts.push(translated);
|
|
150
128
|
}
|
|
151
|
-
}
|
|
152
|
-
|
|
129
|
+
}
|
|
130
|
+
else if (!translated.msgstr[0]) {
|
|
131
|
+
newTxts.push(translated);
|
|
153
132
|
}
|
|
154
133
|
}
|
|
155
134
|
if (loc !== options.sourceLocale && newTxts.length) {
|
|
156
|
-
const geminiT = setupGemini(options.sourceLocale, loc, options.geminiAPIKey)
|
|
135
|
+
const geminiT = setupGemini(options.sourceLocale, loc, options.geminiAPIKey);
|
|
157
136
|
if (geminiT) {
|
|
158
|
-
console.info('Gemini translate', newTxts.length, 'items...')
|
|
159
|
-
await geminiT(newTxts) // will update because it's by reference
|
|
137
|
+
console.info('Gemini translate', newTxts.length, 'items...');
|
|
138
|
+
await geminiT(newTxts); // will update because it's by reference
|
|
160
139
|
}
|
|
161
140
|
}
|
|
162
141
|
for (const nTxt of txts) {
|
|
163
|
-
const key = nTxt.toKey()
|
|
164
|
-
const index = indexTracker.get(key)
|
|
165
|
-
compiled[loc][index] = compileTranslation(translations[loc][key].msgstr[0], compiled[options.sourceLocale][index])
|
|
142
|
+
const key = nTxt.toKey();
|
|
143
|
+
const index = indexTracker.get(key);
|
|
144
|
+
compiled[loc][index] = compileTranslation(translations[loc][key].msgstr[0], compiled[options.sourceLocale][index]);
|
|
166
145
|
}
|
|
167
146
|
for (const [i, c] of compiled[loc].entries()) {
|
|
168
147
|
if (c == null) {
|
|
169
|
-
compiled[loc][i] = 0 // reduce json size for jumped indices, instead of null
|
|
148
|
+
compiled[loc][i] = 0; // reduce json size for jumped indices, instead of null
|
|
170
149
|
}
|
|
171
150
|
}
|
|
172
151
|
if (!newTxts.length) {
|
|
173
|
-
continue
|
|
152
|
+
continue;
|
|
174
153
|
}
|
|
175
154
|
}
|
|
176
155
|
return {
|
|
177
156
|
code: prep.mstr.toString(),
|
|
178
157
|
map: prep.mstr.generateMap(),
|
|
179
|
-
}
|
|
158
|
+
};
|
|
180
159
|
}
|
|
181
|
-
|
|
182
160
|
return {
|
|
183
161
|
name: 'wuchale',
|
|
184
|
-
/**
|
|
185
|
-
* @param {{ env: { PROD: boolean; }, root: string; }} config
|
|
186
|
-
*/
|
|
187
162
|
async configResolved(config) {
|
|
188
|
-
forProduction = config.env.PROD
|
|
189
|
-
projectRoot = config.root
|
|
190
|
-
await loadFilesAndSetup()
|
|
163
|
+
forProduction = config.env.PROD;
|
|
164
|
+
projectRoot = config.root;
|
|
165
|
+
await loadFilesAndSetup();
|
|
191
166
|
},
|
|
192
167
|
transform: {
|
|
193
168
|
order: 'pre',
|
|
194
|
-
|
|
195
|
-
* @param {string} code
|
|
196
|
-
* @param {string} id
|
|
197
|
-
*/
|
|
198
|
-
handler: async function(code, id) {
|
|
169
|
+
handler: async function (code, id) {
|
|
199
170
|
if (!id.startsWith(projectRoot) || id.startsWith(normalize(projectRoot + '/node_modules'))) {
|
|
200
|
-
return
|
|
171
|
+
return;
|
|
201
172
|
}
|
|
202
|
-
const isModule = id.endsWith('.svelte.js') || id.endsWith('.svelte.ts')
|
|
173
|
+
const isModule = id.endsWith('.svelte.js') || id.endsWith('.svelte.ts');
|
|
203
174
|
if (!id.endsWith('.svelte') && !isModule) {
|
|
204
|
-
return
|
|
175
|
+
return;
|
|
205
176
|
}
|
|
206
|
-
let ast
|
|
177
|
+
let ast;
|
|
207
178
|
if (isModule) {
|
|
208
|
-
ast = this.parse(code)
|
|
209
|
-
} else {
|
|
210
|
-
ast = parse(code, {modern: true})
|
|
179
|
+
ast = this.parse(code);
|
|
211
180
|
}
|
|
212
|
-
|
|
213
|
-
|
|
181
|
+
else {
|
|
182
|
+
ast = parse(code, { modern: true });
|
|
183
|
+
}
|
|
184
|
+
const filename = relative(projectRoot, id);
|
|
185
|
+
const processed = await preprocess(code, ast, filename);
|
|
214
186
|
if (processed.code) {
|
|
215
187
|
for (const loc of locales) {
|
|
216
|
-
await savePO(translations[loc], translationsFname[loc])
|
|
217
|
-
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc]))
|
|
188
|
+
await savePO(translations[loc], translationsFname[loc]);
|
|
189
|
+
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc]));
|
|
218
190
|
}
|
|
219
191
|
}
|
|
220
|
-
return processed
|
|
192
|
+
return processed;
|
|
221
193
|
}
|
|
222
194
|
},
|
|
223
195
|
async buildEnd() {
|
|
224
196
|
if (!forProduction) {
|
|
225
197
|
// just being pragmatic
|
|
226
|
-
return
|
|
198
|
+
return;
|
|
227
199
|
}
|
|
228
200
|
for (const loc of locales) {
|
|
229
201
|
for (const key in translations[loc]) {
|
|
230
|
-
const poItem = translations[loc][key]
|
|
231
|
-
poItem.obsolete = poItem.references.length === 0
|
|
202
|
+
const poItem = translations[loc][key];
|
|
203
|
+
poItem.obsolete = poItem.references.length === 0;
|
|
232
204
|
}
|
|
233
|
-
await savePO(translations[loc], translationsFname[loc])
|
|
205
|
+
await savePO(translations[loc], translationsFname[loc]);
|
|
234
206
|
}
|
|
235
207
|
},
|
|
236
208
|
setupTesting() {
|
|
237
209
|
for (const loc of locales) {
|
|
238
|
-
translations[loc] = {}
|
|
239
|
-
compiled[loc] = []
|
|
210
|
+
translations[loc] = {};
|
|
211
|
+
compiled[loc] = [];
|
|
240
212
|
}
|
|
241
|
-
sourceTranslations = translations[options.sourceLocale]
|
|
213
|
+
sourceTranslations = translations[options.sourceLocale];
|
|
242
214
|
return {
|
|
243
215
|
translations,
|
|
244
216
|
compiled,
|
|
245
217
|
preprocess,
|
|
246
|
-
}
|
|
218
|
+
};
|
|
247
219
|
}
|
|
248
|
-
}
|
|
220
|
+
};
|
|
249
221
|
}
|
|
222
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/preprocess/index.ts"],"names":[],"mappings":"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"}
|