wuchale 0.20.0 → 0.21.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/dist/adapter-utils/index.d.ts +2 -0
- package/dist/adapter-utils/index.js +8 -3
- package/dist/adapter-utils/mixed-visitor.d.ts +1 -1
- package/dist/adapter-utils/mixed-visitor.js +28 -13
- package/dist/adapter-vanilla/index.js +2 -1
- package/dist/adapter-vanilla/transformer.d.ts +4 -3
- package/dist/adapter-vanilla/transformer.js +36 -9
- package/dist/adapters.d.ts +12 -11
- package/dist/adapters.js +17 -22
- package/dist/ai/gemini.d.ts +7 -9
- package/dist/ai/gemini.js +2 -1
- package/dist/ai/index.d.ts +10 -7
- package/dist/ai/index.js +115 -49
- package/dist/cli/extract.js +32 -37
- package/dist/cli/status.js +12 -8
- package/dist/compile.d.ts +1 -0
- package/dist/compile.js +31 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +1 -0
- package/dist/handler/files.d.ts +3 -3
- package/dist/handler/files.js +23 -19
- package/dist/handler/index.d.ts +18 -18
- package/dist/handler/index.js +155 -150
- package/dist/handler/state.d.ts +10 -5
- package/dist/handler/state.js +43 -13
- package/dist/handler/url.d.ts +7 -7
- package/dist/handler/url.js +57 -64
- package/dist/index.d.ts +6 -3
- package/dist/index.js +4 -2
- package/dist/pofile.d.ts +23 -0
- package/dist/pofile.js +238 -0
- package/dist/storage.d.ts +59 -0
- package/dist/storage.js +28 -0
- package/dist/url.d.ts +9 -11
- package/dist/url.js +21 -22
- package/package.json +3 -3
- package/src/adapter-vanilla/loaders/bundle.js +1 -1
- package/dist/handler/pofile.d.ts +0 -46
- package/dist/handler/pofile.js +0 -190
|
@@ -3,6 +3,7 @@ import type { HeuristicResultChecked } from '../adapters.js';
|
|
|
3
3
|
export declare const varNames: {
|
|
4
4
|
rt: string;
|
|
5
5
|
hmrUpdate: string;
|
|
6
|
+
urlLocalize: string;
|
|
6
7
|
};
|
|
7
8
|
export declare function runtimeVars(wrapFunc: (expr: string) => string, base?: string): {
|
|
8
9
|
rtTrans: string;
|
|
@@ -21,6 +22,7 @@ export declare function loaderPathResolver(importMetaUrl: string, baseDir: strin
|
|
|
21
22
|
export declare const commentPrefix = "@wc-";
|
|
22
23
|
export type CommentDirectives = {
|
|
23
24
|
ignoreFile?: boolean;
|
|
25
|
+
unit?: boolean;
|
|
24
26
|
forceType?: HeuristicResultChecked;
|
|
25
27
|
context?: string;
|
|
26
28
|
};
|
|
@@ -4,6 +4,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
export const varNames = {
|
|
5
5
|
rt: '_w_runtime_',
|
|
6
6
|
hmrUpdate: '_w_hmrUpdate_',
|
|
7
|
+
urlLocalize: '_w_localize_',
|
|
7
8
|
};
|
|
8
9
|
export function runtimeVars(wrapFunc, base = varNames.rt) {
|
|
9
10
|
return {
|
|
@@ -34,19 +35,23 @@ const commentDirectives = {
|
|
|
34
35
|
ignore: `${commentPrefix}ignore`,
|
|
35
36
|
ignoreFile: `${commentPrefix}ignore-file`,
|
|
36
37
|
include: `${commentPrefix}include`,
|
|
38
|
+
unit: `${commentPrefix}unit`,
|
|
37
39
|
url: `${commentPrefix}url`,
|
|
38
40
|
context: `${commentPrefix}context:`,
|
|
39
41
|
};
|
|
40
42
|
export function updateCommentDirectives(data, directives) {
|
|
41
|
-
if (data === commentDirectives.ignore) {
|
|
42
|
-
directives.forceType = false;
|
|
43
|
-
}
|
|
44
43
|
if (data === commentDirectives.include) {
|
|
45
44
|
directives.forceType = 'message';
|
|
46
45
|
}
|
|
47
46
|
if (data === commentDirectives.url) {
|
|
48
47
|
directives.forceType = 'url';
|
|
49
48
|
}
|
|
49
|
+
if (data === commentDirectives.unit) {
|
|
50
|
+
directives.unit = true;
|
|
51
|
+
}
|
|
52
|
+
if (data === commentDirectives.ignore) {
|
|
53
|
+
directives.forceType = false;
|
|
54
|
+
}
|
|
50
55
|
if (data === commentDirectives.ignoreFile) {
|
|
51
56
|
directives.ignoreFile = true;
|
|
52
57
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type MagicString from 'magic-string';
|
|
2
|
-
import { type HeuristicDetails, type HeuristicDetailsBase, type HeuristicFunc, type IndexTracker, Message, type MessageType } from '../adapters.js';
|
|
2
|
+
import { type HeuristicDetails, type HeuristicDetailsBase, type HeuristicFunc, type IndexTracker, type Message, type MessageType } from '../adapters.js';
|
|
3
3
|
import { type CommentDirectives, type RuntimeVars } from './index.js';
|
|
4
4
|
type NestedRanges = [number, number, boolean][];
|
|
5
5
|
type InitProps<NodeT> = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Shared logic between adapters for handling nested / mixed elements within elements / fragments
|
|
2
|
-
import {
|
|
3
|
-
import { commentPrefix, nonWhitespaceText, updateCommentDirectives, } from './index.js';
|
|
2
|
+
import { getKey, newMessage, } from '../adapters.js';
|
|
3
|
+
import { commentPrefix, nonWhitespaceText, updateCommentDirectives, varNames, } from './index.js';
|
|
4
4
|
export class MixedVisitor {
|
|
5
5
|
constructor(props) {
|
|
6
6
|
Object.assign(this, props);
|
|
@@ -30,16 +30,19 @@ export class MixedVisitor {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
heurStr = heurStr.trimEnd();
|
|
33
|
-
const msg =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
const msg = newMessage({
|
|
34
|
+
msgStr: [heurStr],
|
|
35
|
+
details: this.fullHeuristicDetails({
|
|
36
|
+
scope: props.scope,
|
|
37
|
+
element: props.element,
|
|
38
|
+
attribute: props.attribute,
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
38
41
|
const heurMsgType = this.checkHeuristic(msg);
|
|
39
|
-
if (heurMsgType) {
|
|
42
|
+
if (heurMsgType || props.commentDirectives.unit) {
|
|
40
43
|
const hasCompoundText = hasTextChild && hasNonTextChild;
|
|
41
|
-
if (props.inCompoundText || (hasCompoundText && !hasCommentDirectives)) {
|
|
42
|
-
return [false, hasTextChild, hasCompoundText, heurMsgType, []];
|
|
44
|
+
if (props.inCompoundText || props.commentDirectives.unit || (hasCompoundText && !hasCommentDirectives)) {
|
|
45
|
+
return [false, hasTextChild, hasCompoundText, heurMsgType || 'message', []];
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
// can't be extracted as one; visit each separately if markup
|
|
@@ -99,7 +102,11 @@ export class MixedVisitor {
|
|
|
99
102
|
const chRange = this.getRange(child);
|
|
100
103
|
if (this.isText(child)) {
|
|
101
104
|
const [startWh, trimmed, endWh] = nonWhitespaceText(this.getTextContent(child));
|
|
102
|
-
const msgInfo =
|
|
105
|
+
const msgInfo = newMessage({
|
|
106
|
+
msgStr: [trimmed],
|
|
107
|
+
details: this.fullHeuristicDetails({ scope: props.scope }),
|
|
108
|
+
context: props.commentDirectives.context,
|
|
109
|
+
});
|
|
103
110
|
if (startWh && !msgStr.endsWith(' ')) {
|
|
104
111
|
msgStr += ' ';
|
|
105
112
|
}
|
|
@@ -169,7 +176,11 @@ export class MixedVisitor {
|
|
|
169
176
|
if (!msgStr) {
|
|
170
177
|
return msgs;
|
|
171
178
|
}
|
|
172
|
-
const msgInfo =
|
|
179
|
+
const msgInfo = newMessage({
|
|
180
|
+
msgStr: [msgStr],
|
|
181
|
+
details: this.fullHeuristicDetails({ scope: props.scope }),
|
|
182
|
+
context: props.commentDirectives.context,
|
|
183
|
+
});
|
|
173
184
|
msgInfo.type = heurMsgType;
|
|
174
185
|
msgInfo.placeholders = placeholders;
|
|
175
186
|
if (hasTextChild || hasTextDescendants) {
|
|
@@ -189,7 +200,11 @@ export class MixedVisitor {
|
|
|
189
200
|
begin += `${this.vars().rtTransCtx}(${this.vars().nestCtx}`;
|
|
190
201
|
}
|
|
191
202
|
else {
|
|
192
|
-
|
|
203
|
+
if (msgInfo.type === 'url') {
|
|
204
|
+
begin += `${varNames.urlLocalize}(`;
|
|
205
|
+
end = `), ${this.vars().rtLocale}${end}`;
|
|
206
|
+
}
|
|
207
|
+
begin += `${this.vars().rtTrans}(${this.index.get(getKey(msgInfo.msgStr, msgInfo.context))}`;
|
|
193
208
|
}
|
|
194
209
|
if (iArg > 0) {
|
|
195
210
|
begin += ', [';
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { loaderPathResolver } from '../adapter-utils/index.js';
|
|
3
3
|
import { defaultGenerateLoadID, defaultHeuristicFuncOnly } from '../adapters.js';
|
|
4
4
|
import { deepMergeObjects } from '../config.js';
|
|
5
|
+
import { pofile } from '../pofile.js';
|
|
5
6
|
import { Transformer } from './transformer.js';
|
|
6
7
|
export { Transformer };
|
|
7
8
|
export { parseScript, scriptParseOptions, scriptParseOptionsWithComments } from './transformer.js';
|
|
@@ -11,7 +12,7 @@ export const pluralPattern = {
|
|
|
11
12
|
};
|
|
12
13
|
export const defaultArgs = {
|
|
13
14
|
files: { include: 'src/**/*.{js,ts}', ignore: '**/*.d.ts' },
|
|
14
|
-
|
|
15
|
+
storage: pofile(),
|
|
15
16
|
patterns: [pluralPattern],
|
|
16
17
|
heuristic: defaultHeuristicFuncOnly,
|
|
17
18
|
granularLoad: false,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type * as Estree from 'acorn';
|
|
2
2
|
import MagicString from 'magic-string';
|
|
3
3
|
import { type CommentDirectives, type RuntimeVars } from '../adapter-utils/index.js';
|
|
4
|
-
import type {
|
|
5
|
-
import { Message } from '../adapters.js';
|
|
4
|
+
import type { CodePattern, HeuristicDetails, HeuristicDetailsBase, HeuristicFunc, HeuristicResultChecked, IndexTracker, MessageType, RuntimeConf, RuntimeExpr, TransformOutput, UrlMatcher } from '../adapters.js';
|
|
5
|
+
import { type Message } from '../adapters.js';
|
|
6
6
|
export declare const scriptParseOptions: Estree.Options;
|
|
7
7
|
export declare function scriptParseOptionsWithComments(): [Estree.Options, Estree.Comment[][]];
|
|
8
8
|
export declare function parseScript(content: string): [Estree.Program, Estree.Comment[][]];
|
|
@@ -24,10 +24,11 @@ export declare class Transformer<RTCtxT = {}> {
|
|
|
24
24
|
realBodyStarts: Set<number>;
|
|
25
25
|
/** will be passed to decide which runtime variable to use */
|
|
26
26
|
runtimeCtx: RTCtxT;
|
|
27
|
-
constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr:
|
|
27
|
+
constructor(content: string, filename: string, index: IndexTracker, heuristic: HeuristicFunc, patterns: CodePattern[], catalogExpr: RuntimeExpr, rtConf: RuntimeConf<RTCtxT>, matchUrl: UrlMatcher, rtBaseVars?: string[]);
|
|
28
28
|
fullHeuristicDetails: (detailsBase: HeuristicDetailsBase) => HeuristicDetails;
|
|
29
29
|
getHeuristicMessageType: (msg: Message) => HeuristicResultChecked;
|
|
30
30
|
checkHeuristic: (msgStr: string, detailsBase: HeuristicDetailsBase) => [MessageType, Message] | [false, null];
|
|
31
|
+
literalRepl(msgInfo: Message): string;
|
|
31
32
|
visitLiteral: (node: Estree.Literal, heuristicDetailsBase?: HeuristicDetailsBase) => Message[];
|
|
32
33
|
visitArrayExpression: (node: Estree.ArrayExpression) => Message[];
|
|
33
34
|
visitSequenceExpression: (node: Estree.SequenceExpression) => Message[];
|
|
@@ -3,7 +3,7 @@ import { tsPlugin } from '@sveltejs/acorn-typescript';
|
|
|
3
3
|
import { Parser } from 'acorn';
|
|
4
4
|
import MagicString from 'magic-string';
|
|
5
5
|
import { runtimeVars, updateCommentDirectives, varNames, } from '../adapter-utils/index.js';
|
|
6
|
-
import { defaultHeuristicFuncOnly,
|
|
6
|
+
import { defaultHeuristicFuncOnly, getKey, newMessage } from '../adapters.js';
|
|
7
7
|
export const scriptParseOptions = {
|
|
8
8
|
sourceType: 'module',
|
|
9
9
|
ecmaVersion: 'latest',
|
|
@@ -143,7 +143,11 @@ export class Transformer {
|
|
|
143
143
|
// nothing to ask
|
|
144
144
|
return [false, null];
|
|
145
145
|
}
|
|
146
|
-
const msg =
|
|
146
|
+
const msg = newMessage({
|
|
147
|
+
msgStr: [msgStr],
|
|
148
|
+
details: this.fullHeuristicDetails(detailsBase),
|
|
149
|
+
context: this.commentDirectives.context,
|
|
150
|
+
});
|
|
147
151
|
const heuRes = this.getHeuristicMessageType(msg);
|
|
148
152
|
if (!heuRes) {
|
|
149
153
|
return [false, null];
|
|
@@ -151,6 +155,13 @@ export class Transformer {
|
|
|
151
155
|
msg.type = heuRes;
|
|
152
156
|
return [heuRes, msg];
|
|
153
157
|
};
|
|
158
|
+
literalRepl(msgInfo) {
|
|
159
|
+
let repl = `${this.vars().rtTrans}(${this.index.get(getKey(msgInfo.msgStr, msgInfo.context))})`;
|
|
160
|
+
if (msgInfo.type !== 'url') {
|
|
161
|
+
return repl;
|
|
162
|
+
}
|
|
163
|
+
return `${varNames.urlLocalize}(${repl}, ${this.vars().rtLocale})`;
|
|
164
|
+
}
|
|
154
165
|
visitLiteral = (node, heuristicDetailsBase) => {
|
|
155
166
|
if (typeof node.value !== 'string') {
|
|
156
167
|
return [];
|
|
@@ -160,7 +171,7 @@ export class Transformer {
|
|
|
160
171
|
if (!pass) {
|
|
161
172
|
return [];
|
|
162
173
|
}
|
|
163
|
-
this.mstr.update(start, end,
|
|
174
|
+
this.mstr.update(start, end, this.literalRepl(msgInfo));
|
|
164
175
|
return [msgInfo];
|
|
165
176
|
};
|
|
166
177
|
visitArrayExpression = (node) => node.elements.flatMap(elm => (elm ? this.visit(elm) : []));
|
|
@@ -261,8 +272,12 @@ export class Transformer {
|
|
|
261
272
|
if (typeof argVal.value !== 'string') {
|
|
262
273
|
return this.defaultVisitCallExpression(node);
|
|
263
274
|
}
|
|
264
|
-
const msgInfo =
|
|
265
|
-
|
|
275
|
+
const msgInfo = newMessage({
|
|
276
|
+
msgStr: [argVal.value],
|
|
277
|
+
details: this.fullHeuristicDetails({ scope: 'script' }),
|
|
278
|
+
context: this.commentDirectives.context,
|
|
279
|
+
});
|
|
280
|
+
updates.push([argVal.start, argVal.end, this.literalRepl(msgInfo)]);
|
|
266
281
|
msgs.push(msgInfo);
|
|
267
282
|
continue;
|
|
268
283
|
}
|
|
@@ -281,9 +296,13 @@ export class Transformer {
|
|
|
281
296
|
candidates.push(elm.value);
|
|
282
297
|
}
|
|
283
298
|
// plural(num, ['Form one', 'Form two'])
|
|
284
|
-
const msgInfo =
|
|
299
|
+
const msgInfo = newMessage({
|
|
300
|
+
msgStr: candidates,
|
|
301
|
+
details: this.fullHeuristicDetails({ scope: 'script' }),
|
|
302
|
+
context: this.commentDirectives.context,
|
|
303
|
+
});
|
|
285
304
|
msgInfo.plural = true;
|
|
286
|
-
const index = this.index.get(msgInfo.
|
|
305
|
+
const index = this.index.get(getKey(msgInfo.msgStr, msgInfo.context));
|
|
287
306
|
msgs.push(msgInfo);
|
|
288
307
|
updates.push([argVal.start, argVal.end, `${this.vars().rtTPlural}(${index})`]);
|
|
289
308
|
}
|
|
@@ -542,10 +561,14 @@ export class Transformer {
|
|
|
542
561
|
}
|
|
543
562
|
this.mstr.update(end, end + 2, ', ');
|
|
544
563
|
}
|
|
545
|
-
const msgInfo =
|
|
564
|
+
const msgInfo = newMessage({
|
|
565
|
+
msgStr: [msgStr],
|
|
566
|
+
details: this.fullHeuristicDetails({ scope: 'script' }),
|
|
567
|
+
context: this.commentDirectives.context,
|
|
568
|
+
});
|
|
546
569
|
msgInfo.type = msgTyp;
|
|
547
570
|
msgInfo.placeholders = placeholders;
|
|
548
|
-
const index = this.index.get(msgInfo.
|
|
571
|
+
const index = this.index.get(getKey(msgInfo.msgStr, msgInfo.context));
|
|
549
572
|
msgs.push(msgInfo);
|
|
550
573
|
return [index, msgs];
|
|
551
574
|
};
|
|
@@ -562,6 +585,10 @@ export class Transformer {
|
|
|
562
585
|
const { start: start0, end: end0 } = node.quasis[0];
|
|
563
586
|
let begin = `${this.vars().rtTrans}(${index}`;
|
|
564
587
|
let end = ')';
|
|
588
|
+
if (msgTyp === 'url') {
|
|
589
|
+
begin = `${varNames.urlLocalize}(${begin}`;
|
|
590
|
+
end += `, ${this.vars().rtLocale})`;
|
|
591
|
+
}
|
|
565
592
|
if (node.expressions.length) {
|
|
566
593
|
begin += ', [';
|
|
567
594
|
end = ']' + end;
|
package/dist/adapters.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CompiledElement } from './compile.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { StorageFactory } from './storage.js';
|
|
3
3
|
type TxtScope = 'script' | 'markup' | 'attribute';
|
|
4
4
|
export type HeuristicDetailsBase = {
|
|
5
5
|
scope: TxtScope;
|
|
@@ -17,16 +17,16 @@ export type HeuristicDetails = HeuristicDetailsBase & {
|
|
|
17
17
|
call?: string;
|
|
18
18
|
};
|
|
19
19
|
export type MessageType = 'message' | 'url';
|
|
20
|
-
export
|
|
20
|
+
export type Message = {
|
|
21
21
|
msgStr: string[];
|
|
22
22
|
plural: boolean;
|
|
23
23
|
context?: string;
|
|
24
24
|
placeholders: [number, string][];
|
|
25
25
|
details: HeuristicDetails;
|
|
26
26
|
type: MessageType;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
};
|
|
28
|
+
export declare function newMessage(init: Partial<Message>): Message;
|
|
29
|
+
export declare const getKey: (text: string[], context?: string) => string;
|
|
30
30
|
export type HeuristicResultChecked = MessageType | false;
|
|
31
31
|
export type HeuristicResult = HeuristicResultChecked | null | undefined;
|
|
32
32
|
export type HeuristicFunc = (msg: Message) => HeuristicResult;
|
|
@@ -53,7 +53,7 @@ export type GlobConf = string | string[] | {
|
|
|
53
53
|
include: string | string[];
|
|
54
54
|
ignore: string | string[];
|
|
55
55
|
};
|
|
56
|
-
export type
|
|
56
|
+
export type RuntimeExpr = {
|
|
57
57
|
plain: string;
|
|
58
58
|
reactive: string;
|
|
59
59
|
};
|
|
@@ -62,17 +62,18 @@ type TransformCtx = {
|
|
|
62
62
|
content: string;
|
|
63
63
|
filename: string;
|
|
64
64
|
index: IndexTracker;
|
|
65
|
-
expr:
|
|
65
|
+
expr: RuntimeExpr;
|
|
66
66
|
matchUrl: UrlMatcher;
|
|
67
67
|
};
|
|
68
68
|
export type HMRData = {
|
|
69
69
|
version: number;
|
|
70
70
|
data: Record<string, [number, CompiledElement][]>;
|
|
71
71
|
};
|
|
72
|
-
export type
|
|
72
|
+
export type TransformOutputCode = {
|
|
73
73
|
code?: string;
|
|
74
74
|
map?: any;
|
|
75
75
|
};
|
|
76
|
+
export type TransformOutputFunc = (header: string) => TransformOutputCode;
|
|
76
77
|
export type TransformOutput = {
|
|
77
78
|
output: TransformOutputFunc;
|
|
78
79
|
msgs: Message[];
|
|
@@ -102,12 +103,12 @@ export type LoaderPath = {
|
|
|
102
103
|
};
|
|
103
104
|
export type URLConf = {
|
|
104
105
|
patterns?: string[];
|
|
105
|
-
localize?: boolean |
|
|
106
|
+
localize?: boolean | string;
|
|
106
107
|
};
|
|
107
108
|
export type AdapterPassThruOpts<RTCtxT extends {} = {}> = {
|
|
108
109
|
sourceLocale?: string;
|
|
109
110
|
files: GlobConf;
|
|
110
|
-
|
|
111
|
+
storage: StorageFactory;
|
|
111
112
|
/** if writing transformed code to a directory is desired, specify this */
|
|
112
113
|
outDir?: string;
|
|
113
114
|
granularLoad: boolean;
|
|
@@ -123,7 +124,7 @@ export type Adapter<RTCtxT extends {} = {}> = AdapterPassThruOpts<RTCtxT> & {
|
|
|
123
124
|
/** default loaders to copy, `null` means custom */
|
|
124
125
|
defaultLoaderPath: LoaderPath | string | null;
|
|
125
126
|
/** names to import from loaders, should avoid collision with code variables */
|
|
126
|
-
getRuntimeVars?: Partial<
|
|
127
|
+
getRuntimeVars?: Partial<RuntimeExpr>;
|
|
127
128
|
};
|
|
128
129
|
export type CodePattern = {
|
|
129
130
|
name: string;
|
package/dist/adapters.js
CHANGED
|
@@ -1,27 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
context;
|
|
6
|
-
placeholders = [];
|
|
7
|
-
details;
|
|
8
|
-
type = 'message';
|
|
9
|
-
constructor(msgStr, heuristicDetails = someHeuDet, context) {
|
|
10
|
-
if (typeof msgStr === 'string') {
|
|
11
|
-
this.msgStr = [msgStr];
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
this.msgStr = msgStr.filter(str => str != null);
|
|
15
|
-
}
|
|
16
|
-
this.msgStr = this.msgStr.map(msg => msg
|
|
17
|
-
.split('\n')
|
|
18
|
-
.map(line => line.trim())
|
|
19
|
-
.join('\n'));
|
|
20
|
-
this.details = heuristicDetails;
|
|
21
|
-
this.context = context;
|
|
1
|
+
export function newMessage(init) {
|
|
2
|
+
init.msgStr = init.msgStr?.filter(str => str != null) ?? [];
|
|
3
|
+
if (init.details?.scope === 'markup') {
|
|
4
|
+
init.msgStr = init.msgStr.map(msg => msg.replace(/\s+/g, ' ').trim());
|
|
22
5
|
}
|
|
23
|
-
|
|
6
|
+
return {
|
|
7
|
+
msgStr: init.msgStr,
|
|
8
|
+
plural: init.plural ?? false,
|
|
9
|
+
placeholders: init.placeholders ?? [],
|
|
10
|
+
type: init.type ?? 'message',
|
|
11
|
+
context: init.context,
|
|
12
|
+
details: init.details ?? {
|
|
13
|
+
file: '',
|
|
14
|
+
scope: 'markup',
|
|
15
|
+
insideProgram: true,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
24
18
|
}
|
|
19
|
+
export const getKey = (text, context) => `${text.join('\n')}\n${context ?? ''}`.trim();
|
|
25
20
|
export const defaultHeuristicOpts = {
|
|
26
21
|
ignoreElements: ['script', 'style', 'path', 'code', 'pre'],
|
|
27
22
|
ignoreAttribs: [['form', 'method']],
|
package/dist/ai/gemini.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import type { AI } from './index.js';
|
|
2
|
-
type GeminiOpts = {
|
|
3
|
-
apiKey
|
|
4
|
-
model
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
-
export declare function gemini({ apiKey, model, batchSize, think, parallel, }?: GeminiOpts): AI | null;
|
|
1
|
+
import type { AI, AIPassThruOpts } from './index.js';
|
|
2
|
+
type GeminiOpts = Partial<AIPassThruOpts & {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
model: string;
|
|
5
|
+
think: boolean;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function gemini({ apiKey, model, group, batchSize, think, parallel, }?: GeminiOpts): AI | null;
|
|
10
8
|
export declare const defaultGemini: AI | null;
|
|
11
9
|
export {};
|
package/dist/ai/gemini.js
CHANGED
|
@@ -15,7 +15,7 @@ function prepareData(content, instruction, think) {
|
|
|
15
15
|
},
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
export function gemini({ apiKey = 'env', model = 'gemini-2.5-flash', batchSize = 50, think = false, parallel = 4, } = {}) {
|
|
18
|
+
export function gemini({ apiKey = 'env', model = 'gemini-2.5-flash', group = {}, batchSize = 50, think = false, parallel = 4, } = {}) {
|
|
19
19
|
if (apiKey === 'env') {
|
|
20
20
|
apiKey = process.env.GEMINI_API_KEY ?? '';
|
|
21
21
|
}
|
|
@@ -25,6 +25,7 @@ export function gemini({ apiKey = 'env', model = 'gemini-2.5-flash', batchSize =
|
|
|
25
25
|
return {
|
|
26
26
|
name: 'Gemini',
|
|
27
27
|
batchSize,
|
|
28
|
+
group,
|
|
28
29
|
parallel,
|
|
29
30
|
translate: async (content, instruction) => {
|
|
30
31
|
const data = prepareData(content, instruction, think);
|
package/dist/ai/index.d.ts
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
import { type Item } from '../handler/pofile.js';
|
|
2
1
|
import { type Logger } from '../log.js';
|
|
2
|
+
import type { Item } from '../storage.js';
|
|
3
3
|
type Batch = {
|
|
4
4
|
id: number;
|
|
5
|
+
targetLocales: string[];
|
|
5
6
|
messages: Item[];
|
|
6
7
|
};
|
|
7
|
-
export type
|
|
8
|
-
name: string;
|
|
8
|
+
export type AIPassThruOpts = {
|
|
9
9
|
batchSize: number;
|
|
10
|
-
translate: (messages: string, instruction: string) => Promise<string>;
|
|
11
10
|
parallel: number;
|
|
11
|
+
group: Record<string, string[][]>;
|
|
12
|
+
};
|
|
13
|
+
export type AI = AIPassThruOpts & {
|
|
14
|
+
name: string;
|
|
15
|
+
translate: (messages: string, instruction: string) => Promise<string>;
|
|
12
16
|
};
|
|
13
17
|
export default class AIQueue {
|
|
14
18
|
#private;
|
|
15
19
|
batches: Batch[];
|
|
16
20
|
nextBatchId: number;
|
|
17
21
|
running: Promise<void> | null;
|
|
18
|
-
|
|
19
|
-
targetLang: string;
|
|
22
|
+
sourceLocale: string;
|
|
20
23
|
ai: AI;
|
|
21
24
|
instruction: string;
|
|
22
25
|
onComplete: () => Promise<void>;
|
|
23
26
|
log: Logger;
|
|
24
|
-
constructor(
|
|
27
|
+
constructor(sourceLocale: string, ai: AI, onComplete: () => Promise<void>, log: Logger);
|
|
25
28
|
translate: (batch: Batch, attempt?: number) => Promise<void>;
|
|
26
29
|
run: () => Promise<void>;
|
|
27
30
|
add: (messages: Item[]) => void;
|