wuchale 0.3.2 → 0.4.1

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 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` variable
296
- declaration. This is to make the behavior less magic and being more explicit.
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>
@@ -349,10 +349,10 @@ To configure `wuchale`, you pass an object that looks like the following (the
349
349
  default) to `wuchale()` in your `vite.config.js` `vite.config.ts`:
350
350
 
351
351
  ```javascript
352
- export const defaultOptions = {
352
+ export const defaultOptions: Options = {
353
353
  sourceLocale: 'en',
354
- otherLocales: ['am'],
355
- localesDir: './locales',
354
+ otherLocales: [],
355
+ localesDir: './src/locales',
356
356
  heuristic: defaultHeuristic,
357
357
  geminiAPIKey: 'env',
358
358
  }
@@ -0,0 +1,2 @@
1
+ import plugin from "./preprocess/index.js";
2
+ export declare const wuchale: typeof plugin;
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import plugin from "./preprocess/index.js";
2
+ export const wuchale = plugin;
3
+ //# sourceMappingURL=index.js.map
@@ -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,4 @@
1
+ type CompiledNestedFragment = (string | number | CompiledNestedFragment)[];
2
+ export type CompiledFragment = string | number | CompiledNestedFragment;
3
+ export default function compileTranslation(text: string, fallback: CompiledFragment): CompiledFragment;
4
+ export {};
@@ -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"}
@@ -0,0 +1,4 @@
1
+ import PO from 'pofile';
2
+ export type ItemType = InstanceType<typeof PO.Item>;
3
+ declare function setupGemini(sourceLocale: string, targetLocale: string, apiKey: string | null): (fragments: ItemType[]) => Promise<void>;
4
+ export default setupGemini;
@@ -1,23 +1,17 @@
1
1
  // $$ cd .. && npm run test
2
2
  // $$ node %f
3
-
4
- import PO from 'pofile'
5
-
6
- const baseURL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key='
7
- const h = {'Content-Type': 'application/json'}
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
- You have to find out the languages using their ISO 639-1 codes.
19
- The source language is: ${sourceLocale}.
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 (/** @type {import('pofile').Item[]} */ fragments) => {
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].content.parts[0].text
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
- export default setupGemini
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,45 @@
1
+ import { type HeuristicFunc } 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 interface Options {
6
+ sourceLocale?: string;
7
+ otherLocales?: string[];
8
+ localesDir?: string;
9
+ heuristic?: HeuristicFunc;
10
+ geminiAPIKey?: string;
11
+ }
12
+ export declare const defaultOptions: Options;
13
+ export default function wuchale(options?: Options): Promise<{
14
+ name: string;
15
+ configResolved(config: {
16
+ env: {
17
+ PROD?: boolean;
18
+ };
19
+ root: string;
20
+ }): Promise<void>;
21
+ transform: {
22
+ order: "pre";
23
+ handler: (code: string, id: string) => Promise<{
24
+ code?: undefined;
25
+ map?: undefined;
26
+ } | {
27
+ code: string;
28
+ map: import("magic-string").SourceMap;
29
+ }>;
30
+ };
31
+ buildEnd(): Promise<void>;
32
+ setupTesting(): {
33
+ translations: {};
34
+ compiled: {
35
+ [locale: string]: CompiledFragment[];
36
+ };
37
+ preprocess: (content: string, ast: AST.Root | Program, filename: string) => Promise<{
38
+ code?: undefined;
39
+ map?: undefined;
40
+ } | {
41
+ code: string;
42
+ map: import("magic-string").SourceMap;
43
+ }>;
44
+ };
45
+ }>;
@@ -1,248 +1,223 @@
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
- otherLocales: ['am'],
10
+ otherLocales: [],
12
11
  localesDir: './src/locales',
13
12
  heuristic: defaultHeuristic,
14
13
  geminiAPIKey: 'env',
14
+ };
15
+ function mergeOptionsWithDefault(options = defaultOptions) {
16
+ for (const key of Object.keys(defaultOptions)) {
17
+ if (key in options) {
18
+ continue;
19
+ }
20
+ options[key] = defaultOptions[key];
21
+ }
15
22
  }
16
-
17
- /**
18
- * @param {string} filename
19
- */
20
23
  async function loadPONoFail(filename) {
21
24
  return new Promise((res) => {
22
25
  PO.load(filename, (err, po) => {
23
- const translations = {}
24
- let total = 0
25
- let obsolete = 0
26
- let untranslated = 0
26
+ const translations = {};
27
+ let total = 0;
28
+ let obsolete = 0;
29
+ let untranslated = 0;
27
30
  if (!err) {
28
31
  for (const item of po.items) {
29
- total++
32
+ total++;
30
33
  if (item.obsolete) {
31
- obsolete++
32
- continue
34
+ obsolete++;
35
+ continue;
33
36
  }
34
37
  if (!item.msgstr[0]) {
35
- untranslated++
38
+ untranslated++;
36
39
  }
37
- const nTxt = new NestText(item.msgid, null, item.msgctxt)
38
- translations[nTxt.toKey()] = item
40
+ const nTxt = new NestText(item.msgid, null, item.msgctxt);
41
+ translations[nTxt.toKey()] = item;
39
42
  }
40
43
  }
41
- res({translations, total, obsolete, untranslated})
42
- })
43
- })
44
+ res({ translations, total, obsolete, untranslated });
45
+ });
46
+ });
44
47
  }
45
-
46
- /**
47
- * @param {{ [s: string]: any; } | ArrayLike<any>} translations
48
- * @param {string} filename
49
- */
50
48
  async function savePO(translations, filename) {
51
- const po = new PO()
49
+ const po = new PO();
52
50
  for (const item of Object.values(translations)) {
53
- po.items.push(item)
51
+ po.items.push(item);
54
52
  }
55
53
  return new Promise((res, rej) => {
56
54
  po.save(filename, err => {
57
55
  if (err) {
58
- rej(err)
59
- } else {
60
- res()
56
+ rej(err);
61
57
  }
62
- })
63
- })
64
- }
65
-
66
- function mergeOptionsWithDefault(options = defaultOptions) {
67
- for (const key of Object.keys(defaultOptions)) {
68
- if (key in options) {
69
- continue
70
- }
71
- options[key] = defaultOptions[key]
72
- }
58
+ else {
59
+ res(null);
60
+ }
61
+ });
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 forProduction = false
87
- let projectRoot = ''
88
-
89
- let sourceTranslations = {}
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
- } else if (!translated.msgstr[0]) {
151
- newTxts.push(translated)
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
-
160
+ const order = 'pre';
181
161
  return {
182
162
  name: 'wuchale',
183
- /**
184
- * @param {{ env: { PROD: boolean; }, root: string; }} config
185
- */
186
163
  async configResolved(config) {
187
- forProduction = config.env.PROD
188
- projectRoot = config.root
189
- await loadFilesAndSetup()
164
+ forProduction = config.env.PROD;
165
+ projectRoot = config.root;
166
+ await loadFilesAndSetup();
190
167
  },
191
168
  transform: {
192
- order: 'pre',
193
- /**
194
- * @param {string} code
195
- * @param {string} id
196
- */
197
- handler: async function(code, id) {
169
+ order,
170
+ handler: async function (code, id) {
198
171
  if (!id.startsWith(projectRoot) || id.startsWith(normalize(projectRoot + '/node_modules'))) {
199
- return
172
+ return;
200
173
  }
201
- const isModule = id.endsWith('.svelte.js') || id.endsWith('.svelte.ts')
174
+ const isModule = id.endsWith('.svelte.js') || id.endsWith('.svelte.ts');
202
175
  if (!id.endsWith('.svelte') && !isModule) {
203
- return
176
+ return;
204
177
  }
205
- let ast
178
+ let ast;
206
179
  if (isModule) {
207
- ast = this.parse(code)
208
- } else {
209
- ast = parse(code, {modern: true})
180
+ ast = this.parse(code);
181
+ }
182
+ else {
183
+ ast = parse(code, { modern: true });
210
184
  }
211
- const filename = relative(projectRoot, id)
212
- const processed = await preprocess(code, ast, filename)
185
+ const filename = relative(projectRoot, id);
186
+ const processed = await preprocess(code, ast, filename);
213
187
  if (processed.code) {
214
188
  for (const loc of locales) {
215
- await savePO(translations[loc], translationsFname[loc])
216
- await writeFile(compiledFname[loc], JSON.stringify(compiled[loc]))
189
+ await savePO(translations[loc], translationsFname[loc]);
190
+ await writeFile(compiledFname[loc], JSON.stringify(compiled[loc]));
217
191
  }
218
192
  }
219
- return processed
193
+ return processed;
220
194
  }
221
195
  },
222
196
  async buildEnd() {
223
197
  if (!forProduction) {
224
198
  // just being pragmatic
225
- return
199
+ return;
226
200
  }
227
201
  for (const loc of locales) {
228
202
  for (const key in translations[loc]) {
229
- const poItem = translations[loc][key]
230
- poItem.obsolete = poItem.references.length === 0
203
+ const poItem = translations[loc][key];
204
+ poItem.obsolete = poItem.references.length === 0;
231
205
  }
232
- await savePO(translations[loc], translationsFname[loc])
206
+ await savePO(translations[loc], translationsFname[loc]);
233
207
  }
234
208
  },
235
209
  setupTesting() {
236
210
  for (const loc of locales) {
237
- translations[loc] = {}
238
- compiled[loc] = []
211
+ translations[loc] = {};
212
+ compiled[loc] = [];
239
213
  }
240
- sourceTranslations = translations[options.sourceLocale]
214
+ sourceTranslations = translations[options.sourceLocale];
241
215
  return {
242
216
  translations,
243
217
  compiled,
244
218
  preprocess,
245
- }
219
+ };
246
220
  }
247
- }
221
+ };
248
222
  }
223
+ //# 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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"}