wuchale 0.3.2 → 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 +4 -4
- 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 +107 -133
- 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
|
@@ -102,7 +102,7 @@ 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
|
|
|
@@ -292,9 +292,9 @@ This includes all JS/TS code that is:
|
|
|
292
292
|
The rule for this is that all strings and template strings that start with
|
|
293
293
|
capital letters are extracted. Additionally, if they are used inside the
|
|
294
294
|
`<script>` tags and in their own files (third case above), there is the
|
|
295
|
-
additional restriction that they must be inside a `$derived`
|
|
296
|
-
declaration. This is to make the behavior less magic and being more
|
|
297
|
-
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:
|
|
298
298
|
|
|
299
299
|
```svelte
|
|
300
300
|
<script>
|
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,248 +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
11
|
localesDir: './src/locales',
|
|
13
12
|
heuristic: defaultHeuristic,
|
|
14
13
|
geminiAPIKey: 'env',
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* @param {string} filename
|
|
19
|
-
*/
|
|
14
|
+
};
|
|
20
15
|
async function loadPONoFail(filename) {
|
|
21
16
|
return new Promise((res) => {
|
|
22
17
|
PO.load(filename, (err, po) => {
|
|
23
|
-
const translations = {}
|
|
24
|
-
let total = 0
|
|
25
|
-
let obsolete = 0
|
|
26
|
-
let untranslated = 0
|
|
18
|
+
const translations = {};
|
|
19
|
+
let total = 0;
|
|
20
|
+
let obsolete = 0;
|
|
21
|
+
let untranslated = 0;
|
|
27
22
|
if (!err) {
|
|
28
23
|
for (const item of po.items) {
|
|
29
|
-
total
|
|
24
|
+
total++;
|
|
30
25
|
if (item.obsolete) {
|
|
31
|
-
obsolete
|
|
32
|
-
continue
|
|
26
|
+
obsolete++;
|
|
27
|
+
continue;
|
|
33
28
|
}
|
|
34
29
|
if (!item.msgstr[0]) {
|
|
35
|
-
untranslated
|
|
30
|
+
untranslated++;
|
|
36
31
|
}
|
|
37
|
-
const nTxt = new NestText(item.msgid, null, item.msgctxt)
|
|
38
|
-
translations[nTxt.toKey()] = item
|
|
32
|
+
const nTxt = new NestText(item.msgid, null, item.msgctxt);
|
|
33
|
+
translations[nTxt.toKey()] = item;
|
|
39
34
|
}
|
|
40
35
|
}
|
|
41
|
-
res({translations, total, obsolete, untranslated})
|
|
42
|
-
})
|
|
43
|
-
})
|
|
36
|
+
res({ translations, total, obsolete, untranslated });
|
|
37
|
+
});
|
|
38
|
+
});
|
|
44
39
|
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @param {{ [s: string]: any; } | ArrayLike<any>} translations
|
|
48
|
-
* @param {string} filename
|
|
49
|
-
*/
|
|
50
40
|
async function savePO(translations, filename) {
|
|
51
|
-
const po = new PO()
|
|
41
|
+
const po = new PO();
|
|
52
42
|
for (const item of Object.values(translations)) {
|
|
53
|
-
po.items.push(item)
|
|
43
|
+
po.items.push(item);
|
|
54
44
|
}
|
|
55
45
|
return new Promise((res, rej) => {
|
|
56
46
|
po.save(filename, err => {
|
|
57
47
|
if (err) {
|
|
58
|
-
rej(err)
|
|
59
|
-
}
|
|
60
|
-
|
|
48
|
+
rej(err);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
res(null);
|
|
61
52
|
}
|
|
62
|
-
})
|
|
63
|
-
})
|
|
53
|
+
});
|
|
54
|
+
});
|
|
64
55
|
}
|
|
65
|
-
|
|
66
56
|
function mergeOptionsWithDefault(options = defaultOptions) {
|
|
67
57
|
for (const key of Object.keys(defaultOptions)) {
|
|
68
58
|
if (key in options) {
|
|
69
|
-
continue
|
|
59
|
+
continue;
|
|
70
60
|
}
|
|
71
|
-
options[key] = defaultOptions[key]
|
|
61
|
+
options[key] = defaultOptions[key];
|
|
72
62
|
}
|
|
73
63
|
}
|
|
74
|
-
|
|
75
64
|
export default async function wuchale(options = defaultOptions) {
|
|
76
|
-
mergeOptionsWithDefault(options)
|
|
77
|
-
const locales = [options.sourceLocale, ...options.otherLocales]
|
|
78
|
-
const translations = {}
|
|
79
|
-
const compiledFname = {}
|
|
80
|
-
const translationsFname = {}
|
|
65
|
+
mergeOptionsWithDefault(options);
|
|
66
|
+
const locales = [options.sourceLocale, ...options.otherLocales];
|
|
67
|
+
const translations = {};
|
|
68
|
+
const compiledFname = {};
|
|
69
|
+
const translationsFname = {};
|
|
81
70
|
for (const loc of locales) {
|
|
82
|
-
compiledFname[loc] = `${options.localesDir}/${loc}.json
|
|
83
|
-
translationsFname[loc] = `${options.localesDir}/${loc}.po
|
|
71
|
+
compiledFname[loc] = `${options.localesDir}/${loc}.json`;
|
|
72
|
+
translationsFname[loc] = `${options.localesDir}/${loc}.po`;
|
|
84
73
|
}
|
|
85
|
-
|
|
86
|
-
let
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
let indexTracker = new IndexTracker({})
|
|
91
|
-
|
|
92
|
-
const compiled = {}
|
|
93
|
-
|
|
74
|
+
let forProduction = false;
|
|
75
|
+
let projectRoot = '';
|
|
76
|
+
let sourceTranslations = {};
|
|
77
|
+
let indexTracker = new IndexTracker({});
|
|
78
|
+
const compiled = {};
|
|
94
79
|
async function loadFilesAndSetup() {
|
|
95
80
|
for (const loc of locales) {
|
|
96
|
-
const {translations: trans, total, obsolete, untranslated} = await loadPONoFail(translationsFname[loc])
|
|
97
|
-
translations[loc] = trans
|
|
98
|
-
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}`);
|
|
99
84
|
}
|
|
100
|
-
sourceTranslations = translations[options.sourceLocale]
|
|
101
|
-
indexTracker = new IndexTracker(sourceTranslations)
|
|
85
|
+
sourceTranslations = translations[options.sourceLocale];
|
|
86
|
+
indexTracker = new IndexTracker(sourceTranslations);
|
|
102
87
|
// startup compile
|
|
103
88
|
for (const loc of locales) {
|
|
104
|
-
compiled[loc] = []
|
|
89
|
+
compiled[loc] = [];
|
|
105
90
|
for (const key in translations[loc]) {
|
|
106
|
-
const poItem = translations[loc][key]
|
|
91
|
+
const poItem = translations[loc][key];
|
|
107
92
|
if (forProduction) {
|
|
108
|
-
poItem.references = []
|
|
93
|
+
poItem.references = [];
|
|
109
94
|
}
|
|
110
|
-
const index = indexTracker.get(key)
|
|
111
|
-
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]);
|
|
112
97
|
}
|
|
113
|
-
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc], null, 2))
|
|
98
|
+
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc], null, 2));
|
|
114
99
|
}
|
|
115
100
|
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* @param {string} content
|
|
119
|
-
* @param {import('estree').Program | import("svelte/compiler").AST.Root} ast
|
|
120
|
-
* @param {string} filename
|
|
121
|
-
*/
|
|
122
101
|
async function preprocess(content, ast, filename) {
|
|
123
|
-
const prep = new Preprocess(indexTracker, options.heuristic)
|
|
124
|
-
const txts = prep.process(content, ast)
|
|
102
|
+
const prep = new Preprocess(indexTracker, options.heuristic);
|
|
103
|
+
const txts = prep.process(content, ast);
|
|
125
104
|
if (!txts.length) {
|
|
126
|
-
return {}
|
|
105
|
+
return {};
|
|
127
106
|
}
|
|
128
107
|
for (const loc of locales) {
|
|
129
|
-
const newTxts = []
|
|
108
|
+
const newTxts = [];
|
|
130
109
|
for (const nTxt of txts) {
|
|
131
|
-
let key = nTxt.toKey()
|
|
132
|
-
let translated = translations[loc][key]
|
|
110
|
+
let key = nTxt.toKey();
|
|
111
|
+
let translated = translations[loc][key];
|
|
133
112
|
if (translated == null) {
|
|
134
|
-
translated = new PO.Item()
|
|
135
|
-
translated.msgid = nTxt.toString()
|
|
136
|
-
translations[loc][key] = translated
|
|
113
|
+
translated = new PO.Item();
|
|
114
|
+
translated.msgid = nTxt.toString();
|
|
115
|
+
translations[loc][key] = translated;
|
|
137
116
|
}
|
|
138
117
|
if (nTxt.context) {
|
|
139
|
-
translated.msgctxt = nTxt.context
|
|
118
|
+
translated.msgctxt = nTxt.context;
|
|
140
119
|
}
|
|
141
120
|
if (!translated.references.includes(filename)) {
|
|
142
|
-
translated.references.push(filename)
|
|
121
|
+
translated.references.push(filename);
|
|
143
122
|
}
|
|
144
123
|
if (loc === options.sourceLocale) {
|
|
145
|
-
const txt = nTxt.toString()
|
|
124
|
+
const txt = nTxt.toString();
|
|
146
125
|
if (translated.msgstr[0] !== txt) {
|
|
147
|
-
translated.msgstr = [txt]
|
|
148
|
-
newTxts.push(translated)
|
|
126
|
+
translated.msgstr = [txt];
|
|
127
|
+
newTxts.push(translated);
|
|
149
128
|
}
|
|
150
|
-
}
|
|
151
|
-
|
|
129
|
+
}
|
|
130
|
+
else if (!translated.msgstr[0]) {
|
|
131
|
+
newTxts.push(translated);
|
|
152
132
|
}
|
|
153
133
|
}
|
|
154
134
|
if (loc !== options.sourceLocale && newTxts.length) {
|
|
155
|
-
const geminiT = setupGemini(options.sourceLocale, loc, options.geminiAPIKey)
|
|
135
|
+
const geminiT = setupGemini(options.sourceLocale, loc, options.geminiAPIKey);
|
|
156
136
|
if (geminiT) {
|
|
157
|
-
console.info('Gemini translate', newTxts.length, 'items...')
|
|
158
|
-
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
|
|
159
139
|
}
|
|
160
140
|
}
|
|
161
141
|
for (const nTxt of txts) {
|
|
162
|
-
const key = nTxt.toKey()
|
|
163
|
-
const index = indexTracker.get(key)
|
|
164
|
-
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]);
|
|
165
145
|
}
|
|
166
146
|
for (const [i, c] of compiled[loc].entries()) {
|
|
167
147
|
if (c == null) {
|
|
168
|
-
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
|
|
169
149
|
}
|
|
170
150
|
}
|
|
171
151
|
if (!newTxts.length) {
|
|
172
|
-
continue
|
|
152
|
+
continue;
|
|
173
153
|
}
|
|
174
154
|
}
|
|
175
155
|
return {
|
|
176
156
|
code: prep.mstr.toString(),
|
|
177
157
|
map: prep.mstr.generateMap(),
|
|
178
|
-
}
|
|
158
|
+
};
|
|
179
159
|
}
|
|
180
|
-
|
|
181
160
|
return {
|
|
182
161
|
name: 'wuchale',
|
|
183
|
-
/**
|
|
184
|
-
* @param {{ env: { PROD: boolean; }, root: string; }} config
|
|
185
|
-
*/
|
|
186
162
|
async configResolved(config) {
|
|
187
|
-
forProduction = config.env.PROD
|
|
188
|
-
projectRoot = config.root
|
|
189
|
-
await loadFilesAndSetup()
|
|
163
|
+
forProduction = config.env.PROD;
|
|
164
|
+
projectRoot = config.root;
|
|
165
|
+
await loadFilesAndSetup();
|
|
190
166
|
},
|
|
191
167
|
transform: {
|
|
192
168
|
order: 'pre',
|
|
193
|
-
|
|
194
|
-
* @param {string} code
|
|
195
|
-
* @param {string} id
|
|
196
|
-
*/
|
|
197
|
-
handler: async function(code, id) {
|
|
169
|
+
handler: async function (code, id) {
|
|
198
170
|
if (!id.startsWith(projectRoot) || id.startsWith(normalize(projectRoot + '/node_modules'))) {
|
|
199
|
-
return
|
|
171
|
+
return;
|
|
200
172
|
}
|
|
201
|
-
const isModule = id.endsWith('.svelte.js') || id.endsWith('.svelte.ts')
|
|
173
|
+
const isModule = id.endsWith('.svelte.js') || id.endsWith('.svelte.ts');
|
|
202
174
|
if (!id.endsWith('.svelte') && !isModule) {
|
|
203
|
-
return
|
|
175
|
+
return;
|
|
204
176
|
}
|
|
205
|
-
let ast
|
|
177
|
+
let ast;
|
|
206
178
|
if (isModule) {
|
|
207
|
-
ast = this.parse(code)
|
|
208
|
-
} else {
|
|
209
|
-
ast = parse(code, {modern: true})
|
|
179
|
+
ast = this.parse(code);
|
|
210
180
|
}
|
|
211
|
-
|
|
212
|
-
|
|
181
|
+
else {
|
|
182
|
+
ast = parse(code, { modern: true });
|
|
183
|
+
}
|
|
184
|
+
const filename = relative(projectRoot, id);
|
|
185
|
+
const processed = await preprocess(code, ast, filename);
|
|
213
186
|
if (processed.code) {
|
|
214
187
|
for (const loc of locales) {
|
|
215
|
-
await savePO(translations[loc], translationsFname[loc])
|
|
216
|
-
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc]))
|
|
188
|
+
await savePO(translations[loc], translationsFname[loc]);
|
|
189
|
+
await writeFile(compiledFname[loc], JSON.stringify(compiled[loc]));
|
|
217
190
|
}
|
|
218
191
|
}
|
|
219
|
-
return processed
|
|
192
|
+
return processed;
|
|
220
193
|
}
|
|
221
194
|
},
|
|
222
195
|
async buildEnd() {
|
|
223
196
|
if (!forProduction) {
|
|
224
197
|
// just being pragmatic
|
|
225
|
-
return
|
|
198
|
+
return;
|
|
226
199
|
}
|
|
227
200
|
for (const loc of locales) {
|
|
228
201
|
for (const key in translations[loc]) {
|
|
229
|
-
const poItem = translations[loc][key]
|
|
230
|
-
poItem.obsolete = poItem.references.length === 0
|
|
202
|
+
const poItem = translations[loc][key];
|
|
203
|
+
poItem.obsolete = poItem.references.length === 0;
|
|
231
204
|
}
|
|
232
|
-
await savePO(translations[loc], translationsFname[loc])
|
|
205
|
+
await savePO(translations[loc], translationsFname[loc]);
|
|
233
206
|
}
|
|
234
207
|
},
|
|
235
208
|
setupTesting() {
|
|
236
209
|
for (const loc of locales) {
|
|
237
|
-
translations[loc] = {}
|
|
238
|
-
compiled[loc] = []
|
|
210
|
+
translations[loc] = {};
|
|
211
|
+
compiled[loc] = [];
|
|
239
212
|
}
|
|
240
|
-
sourceTranslations = translations[options.sourceLocale]
|
|
213
|
+
sourceTranslations = translations[options.sourceLocale];
|
|
241
214
|
return {
|
|
242
215
|
translations,
|
|
243
216
|
compiled,
|
|
244
217
|
preprocess,
|
|
245
|
-
}
|
|
218
|
+
};
|
|
246
219
|
}
|
|
247
|
-
}
|
|
220
|
+
};
|
|
248
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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"}
|