@menapo/vi18n 0.0.0-stage → 0.1.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/LICENSE +49 -0
- package/README.md +110 -2
- package/dist/apply-Bre-lY9J.js +228 -0
- package/dist/captured-Bj8bO6vd.js +1034 -0
- package/dist/check-D34P-S--.js +1 -0
- package/dist/check-DyrAbv73.js +201 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +41 -0
- package/dist/codec-DuvU2VQy.js +207 -0
- package/dist/collect-Cx4_SKOe.js +13 -0
- package/dist/collisions-CfpZU8e4.js +217 -0
- package/dist/compile-B5Mz6WJm.js +245 -0
- package/dist/compile-Cc97JaW2.js +2502 -0
- package/dist/concurrency-C9UUWuDC.js +96 -0
- package/dist/concurrency-DONL7t4V.js +1 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.js +39 -0
- package/dist/dir-zw6bGMKQ.js +290 -0
- package/dist/duplicates-yuRljQ6h.js +185 -0
- package/dist/engine-B7p40M__.js +531 -0
- package/dist/engine.d.ts +43 -0
- package/dist/engine.js +1241 -0
- package/dist/exclude-Du-Zd_qI.js +26 -0
- package/dist/export-DGsMbcTZ.js +103 -0
- package/dist/extract-Dujlsgnk.js +298 -0
- package/dist/formats-KPIg-08V.js +781 -0
- package/dist/i18next-CrUnKFfh.js +1596 -0
- package/dist/i18next-Rgo-v9l0.js +1 -0
- package/dist/import-Cwdhcywt.js +225 -0
- package/dist/index.d.ts +156 -0
- package/dist/index.js +239 -0
- package/dist/init-BecCTvKi.js +792 -0
- package/dist/library-D5CWvTQs.js +1882 -0
- package/dist/lingui--PcOOYry.js +833 -0
- package/dist/lint.d.ts +105 -0
- package/dist/lint.js +971 -0
- package/dist/load-CQRz4PpM.js +2950 -0
- package/dist/load-gW-oJt1Q.js +747 -0
- package/dist/locales-DX4MOBFE.js +827 -0
- package/dist/lsp-Cq1Nuu-Q.js +31 -0
- package/dist/match-BGr8EXB3.js +89 -0
- package/dist/mcp-Cf0T7qPW.js +28 -0
- package/dist/merge-driver-CpiiSVIc.js +422 -0
- package/dist/messages-Cxa-5tR0.js +166 -0
- package/dist/migrate-CntqvrW4.js +1 -0
- package/dist/migrate-dPgq9uzy.js +1484 -0
- package/dist/openai-CTaMDcl-.js +346 -0
- package/dist/output-DsaHKHEt.js +164 -0
- package/dist/parse.d.ts +62 -0
- package/dist/parse.js +156 -0
- package/dist/pipeline-C7g11THL.js +2031 -0
- package/dist/pipeline-wxS0SApG.js +1 -0
- package/dist/project-Dwx7iPm6.js +381 -0
- package/dist/project-pXipT8iG.js +1046 -0
- package/dist/pseudo-DRv30iN5.js +145 -0
- package/dist/raw-C4Y6vyGY.js +4708 -0
- package/dist/react-intl-CaBVwJ9u.js +519 -0
- package/dist/restore-Btq66Tid.js +175 -0
- package/dist/rewrite-CiTRAICl.js +803 -0
- package/dist/rich-DCUKl5HM.js +97 -0
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/run-DYD_VXKy.js +694 -0
- package/dist/runtime-DTMmliT1.js +64 -0
- package/dist/scan-worker.d.ts +62 -0
- package/dist/scan-worker.js +1 -0
- package/dist/scoped-BMYpSthj.js +44 -0
- package/dist/server-BDkykMjb.js +11823 -0
- package/dist/server-qv3mz70d.js +10485 -0
- package/dist/server.d.ts +169 -0
- package/dist/server.js +1234 -0
- package/dist/sitemap-DV3o8QD7.js +159 -0
- package/dist/sources-D19czDSA.js +2242 -0
- package/dist/status-DZArW5aE.js +149 -0
- package/dist/stdio-CVaJfxA7.js +29 -0
- package/dist/stdio-FPOKQAgu.js +95 -0
- package/dist/sync-CcVzger_.js +658 -0
- package/dist/t-DC-c9zE5.js +454 -0
- package/dist/test.d.ts +116 -0
- package/dist/test.js +319 -0
- package/dist/translate-DZR3MkSA.js +299 -0
- package/dist/ts-BaU5yOf0.js +4863 -0
- package/dist/types-CgUCkFU1.d.ts +707 -0
- package/dist/types-D3QGM8XO.js +146 -0
- package/dist/types-DsdWBG0b.d.ts +558 -0
- package/dist/types-DtvQ7UdD.js +1948 -0
- package/dist/types-wSh9fCBY.js +11 -0
- package/dist/units-CQ5Q99RC.js +150 -0
- package/dist/url-CRfCOhUI.js +172 -0
- package/dist/url-CsBkRaJy.js +225 -0
- package/dist/validate-BxpupdAf.js +2615 -0
- package/dist/validate-D6DJepZv.js +365 -0
- package/dist/version-BlyLGlOa.js +28 -0
- package/dist/vite-scan-B_YW4X_a.js +242 -0
- package/dist/vite.d.ts +34 -0
- package/dist/vite.js +7558 -0
- package/dist/vue-i18n-CEMnpv7k.js +651 -0
- package/dist/which-C6PFI1Dm.js +116 -0
- package/dist/worker-84U6uYB3.js +1656 -0
- package/package.json +97 -3
- package/schemas/catalog.json +57 -0
|
@@ -0,0 +1,707 @@
|
|
|
1
|
+
//#region src/runtime/types.d.ts
|
|
2
|
+
/** Where a locale may come from, in `routing.strategy` order. */
|
|
3
|
+
type LocaleStrategy = "url" | "cookie" | "header" | "localStorage" | "default";
|
|
4
|
+
/** URL codec strategies (Nuxt i18n names); domains are `routing.domains` on top of `prefix_except_default`. */
|
|
5
|
+
type UrlStrategy = "prefix_except_default" | "prefix" | "prefix_and_default" | "no_prefix";
|
|
6
|
+
declare global {
|
|
7
|
+
/**
|
|
8
|
+
* Defined by `vi18n:config` (`true` in `vite dev`, `false` in builds). Runtime
|
|
9
|
+
* code reads it as `typeof __VI18N_DEV__ !== "undefined" && __VI18N_DEV__`, so
|
|
10
|
+
* code bundled without the plugin behaves as production. `var`, not `const`:
|
|
11
|
+
* the two pack configs each inline this file into their own `.d.ts` chunk,
|
|
12
|
+
* and a consumer importing both would hit a block-scoped redeclaration.
|
|
13
|
+
*/
|
|
14
|
+
var __VI18N_DEV__: boolean | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* Defined by `vi18n:config`: whether the config has `routing.paths` or
|
|
17
|
+
* `routing.domains`. Code bundled without the plugin keeps the support
|
|
18
|
+
* (`typeof __VI18N_ROUTES__ === "undefined" || __VI18N_ROUTES__`), and a
|
|
19
|
+
* plugin build of a config without either folds it out (PLAN §6).
|
|
20
|
+
*/
|
|
21
|
+
var __VI18N_ROUTES__: boolean | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Defined by `vi18n:config`: whether `ssr.payload` is `"preload"`. Code
|
|
24
|
+
* bundled without the plugin keeps the support (a Nitro-built `/server`
|
|
25
|
+
* copy reads the registration's config), and a plugin build of the default
|
|
26
|
+
* config folds it out of the engine and `/server` (PLAN §6).
|
|
27
|
+
*/
|
|
28
|
+
var __VI18N_PRELOAD__: boolean | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Defined by `vi18n:config`: whether `output.compactIds` is on. Only the
|
|
31
|
+
* plugin's boot module imports the engine, so undefined reads as false.
|
|
32
|
+
*/
|
|
33
|
+
var __VI18N_COMPACT__: boolean | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Defined by `vi18n:config`: whether `output.perLocale` is on. Undefined
|
|
36
|
+
* is false, as for `__VI18N_COMPACT__`.
|
|
37
|
+
*/
|
|
38
|
+
var __VI18N_INLINE__: boolean | undefined;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/core/types.d.ts
|
|
42
|
+
type Severity = "error" | "warning" | "info";
|
|
43
|
+
/**
|
|
44
|
+
* Every problem vi18n reports has one of these codes. The CLI prints them in
|
|
45
|
+
* `--json` and as GitHub annotation titles (`vi18n(<code>)`).
|
|
46
|
+
*/
|
|
47
|
+
type DiagnosticCode = "icu-syntax" | "icu-missing-other" | "icu-unsupported-type" | "icu-pattern-style" | "icu-pound-nested" | "icu-unknown-skeleton" | "icu-unknown-currency" | "icu-unknown-unit" | "icu-bidi-control" | "icu-unbalanced-isolate" | "icu-argument-mismatch" | "icu-tag-mismatch" | "icu-plural-missing-category" | "icu-plural-unused-category" | "icu-plural-one-literal" | "icu-apostrophe" | "icu-max-length" | "extract-dynamic-message" | "extract-non-literal-option" | "extract-invalid-manual-id" | "extract-module-scope" | "extract-html-sink" | "extract-captured-value" | "extract-wrapper-unused" | "extract-outside-include" | "extract-parse-error" | "extract-missing-compiler" | "extract-empty-root" | "id-collision" | "id-scheme-mismatch" | "catalog-parse" | "catalog-duplicate" | "catalog-wrapped" | "catalog-foreign-context" | "catalog-source-mismatch" | "catalog-fuzzy" | "catalog-invalid-translation" | "catalog-missing-translation" | "catalog-unused-entry" | "catalog-obsolete-dropped" | "catalog-safety-limit" | "catalog-drift" | "catalog-write-conflict" | "keep-missing-entry" | "import-parse" | "import-skipped" | "restore-git" | "merge-conflict" | "config-invalid" | "config-not-found" | "build-guard-skipped" | "build-dead-messages" | "ai-validation-failed" | "ai-identical-output" | "ai-provider-error" | "ai-missing-key" | "ai-cost-limit" | "migrate-dynamic-key" | "migrate-date-placeholder" | "migrate-manual" | "migrate-unconverted";
|
|
48
|
+
interface Diagnostic {
|
|
49
|
+
code: DiagnosticCode;
|
|
50
|
+
severity: Severity;
|
|
51
|
+
/** One sentence, no trailing period, naming what to do when there is a fix. */
|
|
52
|
+
message: string;
|
|
53
|
+
/** Posix path relative to the config root (or absolute outside it). */
|
|
54
|
+
file?: string;
|
|
55
|
+
/** 1-based; 0 or absent when unknown. */
|
|
56
|
+
line?: number;
|
|
57
|
+
column?: number;
|
|
58
|
+
locale?: string;
|
|
59
|
+
/** Message id or manual id concerned. */
|
|
60
|
+
id?: string;
|
|
61
|
+
/** Other places involved, e.g. the second text of a collision. */
|
|
62
|
+
related?: {
|
|
63
|
+
file?: string;
|
|
64
|
+
line?: number;
|
|
65
|
+
column?: number;
|
|
66
|
+
message: string;
|
|
67
|
+
}[];
|
|
68
|
+
/** Offsets in the scanned code; set only under `ScanOptions.ranges` (the `/lint` rules report at them). */
|
|
69
|
+
range?: [number, number];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Errors thrown by core functions (codec, parsers, loaders) carry the
|
|
73
|
+
* diagnostic, so callers in any module can report them without `instanceof`.
|
|
74
|
+
*/
|
|
75
|
+
interface DiagnosticError extends Error {
|
|
76
|
+
diagnostic: Diagnostic;
|
|
77
|
+
}
|
|
78
|
+
/** UTF-16 offsets into the parsed string (after NFC and LF normalisation). */
|
|
79
|
+
interface IcuLoc {
|
|
80
|
+
start: number;
|
|
81
|
+
end: number;
|
|
82
|
+
}
|
|
83
|
+
type IcuNode = IcuLiteral | IcuArgument | IcuFormatted | IcuSelect | IcuPlural | IcuPound | IcuTag;
|
|
84
|
+
/** A parsed message: nodes in order; adjacent literals are merged; `[]` is the empty message. */
|
|
85
|
+
type IcuMessage = IcuNode[];
|
|
86
|
+
/** Literal text with quoting removed (`''` → `'`, `'{'` → `{`). Never empty. */
|
|
87
|
+
interface IcuLiteral {
|
|
88
|
+
type: "literal";
|
|
89
|
+
value: string;
|
|
90
|
+
loc?: IcuLoc;
|
|
91
|
+
}
|
|
92
|
+
/** `{name}` */
|
|
93
|
+
interface IcuArgument {
|
|
94
|
+
type: "argument";
|
|
95
|
+
name: string;
|
|
96
|
+
loc?: IcuLoc;
|
|
97
|
+
}
|
|
98
|
+
/** `{name, number|date|time[, style]}` */
|
|
99
|
+
interface IcuFormatted {
|
|
100
|
+
type: "number" | "date" | "time";
|
|
101
|
+
name: string;
|
|
102
|
+
style: IcuStyle | null;
|
|
103
|
+
/**
|
|
104
|
+
* Intl options resolved by the parser (FormatJS `formats` tables for
|
|
105
|
+
* keywords, skeleton conversion for `::…`). Null when Intl defaults apply.
|
|
106
|
+
*/
|
|
107
|
+
options: {
|
|
108
|
+
[option: string]: string | number | boolean;
|
|
109
|
+
} | null;
|
|
110
|
+
loc?: IcuLoc;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* A style as written, normalised: keywords as-is; skeletons without the
|
|
114
|
+
* leading `::`, tokens separated by exactly one space.
|
|
115
|
+
*/
|
|
116
|
+
type IcuStyle = {
|
|
117
|
+
kind: "keyword";
|
|
118
|
+
value: "integer" | "percent" | "short" | "medium" | "long" | "full";
|
|
119
|
+
} | {
|
|
120
|
+
kind: "skeleton";
|
|
121
|
+
value: string;
|
|
122
|
+
};
|
|
123
|
+
/** One branch of a select or plural, in source order. */
|
|
124
|
+
interface IcuOption {
|
|
125
|
+
/** Select value, `=N` normalised to `"=" + String(Number(N))` (`=01` is `=1`), or a CLDR category / `other`. */
|
|
126
|
+
key: string;
|
|
127
|
+
value: IcuMessage;
|
|
128
|
+
loc?: IcuLoc;
|
|
129
|
+
}
|
|
130
|
+
/** `{name, select, …}` */
|
|
131
|
+
interface IcuSelect {
|
|
132
|
+
type: "select";
|
|
133
|
+
name: string;
|
|
134
|
+
options: IcuOption[];
|
|
135
|
+
loc?: IcuLoc;
|
|
136
|
+
}
|
|
137
|
+
/** `{name, plural|selectordinal, [offset:N] …}` */
|
|
138
|
+
interface IcuPlural {
|
|
139
|
+
type: "plural";
|
|
140
|
+
pluralType: "cardinal" | "ordinal";
|
|
141
|
+
name: string;
|
|
142
|
+
/** 0 when absent. */
|
|
143
|
+
offset: number;
|
|
144
|
+
options: IcuOption[];
|
|
145
|
+
loc?: IcuLoc;
|
|
146
|
+
}
|
|
147
|
+
/** `#` in an immediate plural/selectordinal branch (also inside tags there). */
|
|
148
|
+
interface IcuPound {
|
|
149
|
+
type: "pound";
|
|
150
|
+
loc?: IcuLoc;
|
|
151
|
+
}
|
|
152
|
+
/** `<name>…</name>`, or `<name/>` when `children` is null. No attributes. */
|
|
153
|
+
interface IcuTag {
|
|
154
|
+
type: "tag";
|
|
155
|
+
name: string;
|
|
156
|
+
children: IcuMessage | null;
|
|
157
|
+
loc?: IcuLoc;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The one place that turns source text into ids. Built by `createCodec(length)`
|
|
161
|
+
* (`src/core/codec.ts`). Wave-1 modules receive it as a parameter.
|
|
162
|
+
*/
|
|
163
|
+
interface MessageCodec {
|
|
164
|
+
/** `ids.length`, 8–16. */
|
|
165
|
+
readonly idLength: number;
|
|
166
|
+
/** `sha256-b64u-<idLength>-v2` (PO `X-Vi18n-Id`, JSON `idScheme`). */
|
|
167
|
+
readonly idScheme: string;
|
|
168
|
+
/** NFC + LF, parse, canonical print. Throws a {@link DiagnosticError} (`icu-*`) on invalid ICU. */
|
|
169
|
+
canonicalize(source: string): string;
|
|
170
|
+
/**
|
|
171
|
+
* Parse after NFC + LF normalisation; memoised, so the same AST object is
|
|
172
|
+
* returned for the same string and must not be mutated. Throws like `canonicalize`.
|
|
173
|
+
*/
|
|
174
|
+
parse(source: string): IcuMessage;
|
|
175
|
+
/** `base64url(sha256(utf8(canonical + "\u001F")))`, 43 characters. */
|
|
176
|
+
sourceHash(canonical: string): string;
|
|
177
|
+
/** The first `idLength` characters of `sourceHash`: a generated id, or a manual entry's label. */
|
|
178
|
+
label(canonical: string): string;
|
|
179
|
+
}
|
|
180
|
+
/** How a message argument reached vi18n. */
|
|
181
|
+
type CalleeKind = "t" | "msg" | "rich" | "richHtml" | "richParts" | "alias" | "global" | "translator";
|
|
182
|
+
/** One message at one call site. JSON-serialisable: it is cached and stored in `meta.vi18n`. */
|
|
183
|
+
interface MessageOccurrence {
|
|
184
|
+
/** Generated id (`label`) or the manual id. */
|
|
185
|
+
id: string;
|
|
186
|
+
manual: boolean;
|
|
187
|
+
/** The exact JS string value at the call site (a `sources.json` key). */
|
|
188
|
+
source: string;
|
|
189
|
+
canonical: string;
|
|
190
|
+
/** 43-character hash of `canonical`. */
|
|
191
|
+
sourceHash: string;
|
|
192
|
+
/** Generated id of `canonical`; equals `id` when `manual` is false. */
|
|
193
|
+
label: string;
|
|
194
|
+
/** The `context` note as written (may span lines). */
|
|
195
|
+
context?: string;
|
|
196
|
+
maxLength?: number;
|
|
197
|
+
callee: CalleeKind;
|
|
198
|
+
/** Posix path relative to the config root (a `#:` reference). */
|
|
199
|
+
file: string;
|
|
200
|
+
/** 1-based position in the original file; 0 when not yet located. */
|
|
201
|
+
line: number;
|
|
202
|
+
column: number;
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region src/ai/types.d.ts
|
|
206
|
+
/** Whatever a provider needs to answer one request. One target locale per request. */
|
|
207
|
+
interface ProviderRequest {
|
|
208
|
+
sourceLocale: string;
|
|
209
|
+
targetLocale: string;
|
|
210
|
+
/**
|
|
211
|
+
* Stable system prefix (product description, tone, ICU rules, required plural
|
|
212
|
+
* categories); identical across batches of a locale so implicit caching applies.
|
|
213
|
+
*/
|
|
214
|
+
system: string;
|
|
215
|
+
/** Items to translate, deduplicated across routes; 40–80 per request. */
|
|
216
|
+
items: AiItem[];
|
|
217
|
+
/** JSON Schema of the expected answer (Gemini `responseJsonSchema`). */
|
|
218
|
+
responseSchema: JsonSchema;
|
|
219
|
+
}
|
|
220
|
+
/** One item, sent as data. Text is masked: URLs, e-mail addresses and HTML entities become `@@PHn@@`. */
|
|
221
|
+
interface AiItem {
|
|
222
|
+
/** Catalog key: generated id or manual id. Results are mapped back by this. */
|
|
223
|
+
id: string;
|
|
224
|
+
/** Canonical source, masked. */
|
|
225
|
+
source: string;
|
|
226
|
+
/** The developer's `context` notes, joined with "\n" (D3). */
|
|
227
|
+
context?: string;
|
|
228
|
+
/**
|
|
229
|
+
* Route and file context: the config-relative files that use the message
|
|
230
|
+
* (at most 5, sorted). A file-based router's path names the screen.
|
|
231
|
+
*/
|
|
232
|
+
files?: string[];
|
|
233
|
+
/** Argument names in the source, in first-use order. */
|
|
234
|
+
placeholders: string[];
|
|
235
|
+
/** Tag names in the source. */
|
|
236
|
+
tags: string[];
|
|
237
|
+
maxLength?: number;
|
|
238
|
+
/** Plural categories the target locale needs, when the message has a plural. */
|
|
239
|
+
pluralCategories?: {
|
|
240
|
+
cardinal: string[];
|
|
241
|
+
ordinal: string[];
|
|
242
|
+
};
|
|
243
|
+
/** Nearest non-`ai` translations in the target locale (masked). Never AI output. */
|
|
244
|
+
examples: {
|
|
245
|
+
source: string;
|
|
246
|
+
translation: string;
|
|
247
|
+
}[];
|
|
248
|
+
/** Retries only: the checks the previous answer failed. */
|
|
249
|
+
failingChecks?: string[];
|
|
250
|
+
}
|
|
251
|
+
/** A provider's answer. `items` may be partial; missing ids count as failures. */
|
|
252
|
+
interface ProviderResponse {
|
|
253
|
+
items: {
|
|
254
|
+
id: string;
|
|
255
|
+
translation: string;
|
|
256
|
+
}[];
|
|
257
|
+
usage?: {
|
|
258
|
+
inputTokens: number;
|
|
259
|
+
outputTokens: number;
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/** What the pipeline passes with each request. */
|
|
263
|
+
interface TranslateOptions {
|
|
264
|
+
signal?: AbortSignal;
|
|
265
|
+
/**
|
|
266
|
+
* Call on every rate limit (HTTP 429, `RESOURCE_EXHAUSTED`) before waiting
|
|
267
|
+
* it out, with the delay the server asked for when it named one: the
|
|
268
|
+
* pipeline halves its concurrency and holds new requests that long.
|
|
269
|
+
*/
|
|
270
|
+
onRateLimit?: (retryAfterMs: number | null) => void;
|
|
271
|
+
}
|
|
272
|
+
/** A pluggable translation backend (`ai.provider`). */
|
|
273
|
+
interface TranslationProvider {
|
|
274
|
+
/** `"gemini"`, `"openai-compatible"`, or a custom name. */
|
|
275
|
+
readonly name: string;
|
|
276
|
+
readonly model: string;
|
|
277
|
+
translate(request: ProviderRequest, options?: TranslateOptions): Promise<ProviderResponse>;
|
|
278
|
+
/**
|
|
279
|
+
* `--dry-run` / `--max-cost`: estimated USD for the given token counts, from a
|
|
280
|
+
* pinned price table; `NaN` when the model has no known price.
|
|
281
|
+
*/
|
|
282
|
+
estimateCost?(usage: {
|
|
283
|
+
inputTokens: number;
|
|
284
|
+
outputTokens: number;
|
|
285
|
+
}): number;
|
|
286
|
+
/**
|
|
287
|
+
* The environment variable the key is read from, null when no key is sent.
|
|
288
|
+
* The CLI redacts its value from all output.
|
|
289
|
+
*/
|
|
290
|
+
readonly apiKeyEnv?: string | null;
|
|
291
|
+
/** The `ai-missing-key` a call would fail with now, or null; asked before the first request. */
|
|
292
|
+
missingKey?(): Diagnostic | null;
|
|
293
|
+
/** The same provider with another model (`--model`). */
|
|
294
|
+
withModel?(model: string): TranslationProvider;
|
|
295
|
+
/**
|
|
296
|
+
* P2 Batch tier (`--tier batch`): answers many requests in asynchronous
|
|
297
|
+
* jobs at a lower price, in request order. A request the job failed is a
|
|
298
|
+
* `DiagnosticError` (`ai-provider-error`) in its place; a failed job throws.
|
|
299
|
+
*/
|
|
300
|
+
translateBatch?(requests: readonly ProviderRequest[], options?: BatchOptions): Promise<(ProviderResponse | DiagnosticError)[]>;
|
|
301
|
+
}
|
|
302
|
+
interface BatchOptions {
|
|
303
|
+
signal?: AbortSignal;
|
|
304
|
+
/** Progress while a job runs (its name and state), for the terminal. */
|
|
305
|
+
onProgress?: (progress: {
|
|
306
|
+
job: string;
|
|
307
|
+
state: string;
|
|
308
|
+
requests: number;
|
|
309
|
+
}) => void;
|
|
310
|
+
}
|
|
311
|
+
/** P2 Gemini service tiers (`--tier`); Flex and Batch cost half, Batch answers asynchronously. */
|
|
312
|
+
type Tier = "standard" | "flex" | "batch";
|
|
313
|
+
/** Options shared by provider factories. Keys come only from the environment. */
|
|
314
|
+
interface ProviderOptions {
|
|
315
|
+
model?: string;
|
|
316
|
+
/** Name of the env variable holding the key. */
|
|
317
|
+
apiKeyEnv?: string;
|
|
318
|
+
/** A key is only sent to a host other than the provider's default when `apiKeyEnv` is set explicitly. */
|
|
319
|
+
baseURL?: string;
|
|
320
|
+
/** Gemini only. Default `"standard"`. */
|
|
321
|
+
tier?: Tier;
|
|
322
|
+
/** Injected in tests (recorded fixtures). Defaults to `globalThis.fetch`. */
|
|
323
|
+
fetch?: typeof fetch;
|
|
324
|
+
/** Injected in tests. Defaults to `process.env`. */
|
|
325
|
+
env?: {
|
|
326
|
+
readonly [name: string]: string | undefined;
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
/** `openaiCompatible(options)`: any `/chat/completions` API (OpenAI, OpenRouter, Ollama, Gemini's OpenAI endpoint). */
|
|
330
|
+
interface OpenAICompatibleOptions extends Omit<ProviderOptions, "tier"> {
|
|
331
|
+
model: string;
|
|
332
|
+
/** Default `https://api.openai.com/v1`. */
|
|
333
|
+
baseURL?: string;
|
|
334
|
+
/**
|
|
335
|
+
* Env variable holding the key, sent as `Authorization: Bearer`. Default
|
|
336
|
+
* `OPENAI_API_KEY`, and only to the default host: another host gets no key
|
|
337
|
+
* unless this names one (Ollama needs none).
|
|
338
|
+
*/
|
|
339
|
+
apiKeyEnv?: string;
|
|
340
|
+
/**
|
|
341
|
+
* How the answer's shape is requested: `json_schema` (structured output,
|
|
342
|
+
* the default), `json_object`, or `text` (the prompt alone). A server that
|
|
343
|
+
* refuses one is asked again with the next.
|
|
344
|
+
*/
|
|
345
|
+
responseFormat?: "json_schema" | "json_object" | "text";
|
|
346
|
+
/** USD per 1M input and output tokens, for `--dry-run` and `--max-cost`; without it the cost is unknown. */
|
|
347
|
+
prices?: {
|
|
348
|
+
input: number;
|
|
349
|
+
output: number;
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
/** A JSON Schema object (the Gemini `responseJsonSchema` subset). */
|
|
353
|
+
type JsonSchema = {
|
|
354
|
+
[keyword: string]: unknown;
|
|
355
|
+
};
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/config/types.d.ts
|
|
358
|
+
/** Severity of a `strict` rule. */
|
|
359
|
+
type Level = "off" | "warn" | "error";
|
|
360
|
+
/** The two generated pseudo-locales (PLAN §4.7, §5.21). */
|
|
361
|
+
type PseudoLocale = "en-XA" | "ar-XB";
|
|
362
|
+
/** `vi18n.config.ts` as written. Every key is optional except where noted. */
|
|
363
|
+
interface Vi18nConfig {
|
|
364
|
+
/** Default `"en"`. Also the default locale of URL strategies and negotiation. */
|
|
365
|
+
sourceLocale?: string;
|
|
366
|
+
/** Default `[sourceLocale]`. Must contain `sourceLocale`. */
|
|
367
|
+
locales?: string[];
|
|
368
|
+
/** Default `[]`. Listed pseudo-locales are active in `vite dev` and in builds whose mode is not `production`. */
|
|
369
|
+
pseudoLocales?: PseudoLocale[];
|
|
370
|
+
/** Appended after the tag-derived chain (`de-CH` → `de`), before `sourceLocale`. */
|
|
371
|
+
fallbacks?: {
|
|
372
|
+
[locale: string]: string[];
|
|
373
|
+
};
|
|
374
|
+
project?: {
|
|
375
|
+
/** Directories or files, relative to the config file. Default `["src"]`. */
|
|
376
|
+
include?: string[];
|
|
377
|
+
extensions?: string[];
|
|
378
|
+
/** gitignore-style: a pattern without `/` matches any path segment; one with `/` (a leading `/` too) is a glob from the config root. */
|
|
379
|
+
exclude?: string[];
|
|
380
|
+
};
|
|
381
|
+
extraction?: {
|
|
382
|
+
/** Appended to the defaults `@menapo/vi18n` and `@menapo/vi18n/server`, which always apply. */
|
|
383
|
+
importSources?: string[];
|
|
384
|
+
/** Other exported names that behave like `t` (matched only when imported from an import source). */
|
|
385
|
+
aliases?: string[];
|
|
386
|
+
/** Import-free template callees such as Vue's `$t` (bare, `_ctx.` and `$setup.` forms). */
|
|
387
|
+
globals?: string[];
|
|
388
|
+
/** Ids that always ship (dynamic keys); `base` in SPAs, `shared` otherwise. */
|
|
389
|
+
keep?: string[];
|
|
390
|
+
/**
|
|
391
|
+
* Published packages (by name) whose code vi18n extracts and rewrites
|
|
392
|
+
* like the app's, and whose catalogs it reads under the app's own
|
|
393
|
+
* (`package.json#vi18n`). Default `[]`.
|
|
394
|
+
*/
|
|
395
|
+
dependencies?: string[];
|
|
396
|
+
};
|
|
397
|
+
ids?: {
|
|
398
|
+
/** Base64url characters of every generated id, 8–16. Default 12. Changing it is a re-key. */
|
|
399
|
+
length?: number;
|
|
400
|
+
};
|
|
401
|
+
catalogs?: {
|
|
402
|
+
format?: "po" | "json";
|
|
403
|
+
/** Relative to the config file, with `{locale}`. Default `locales/{locale}.po` (`.json` for JSON). */
|
|
404
|
+
path?: string;
|
|
405
|
+
msgid?: "source" | "id";
|
|
406
|
+
/**
|
|
407
|
+
* PO only: mark every entry `#, icu-message-format`, which turns on
|
|
408
|
+
* Weblate's ICU MessageFormat checks. vi18n owns the flag: `vi18n extract`
|
|
409
|
+
* adds it to every entry, or removes it when false. Default false.
|
|
410
|
+
*/
|
|
411
|
+
icuFlag?: boolean;
|
|
412
|
+
};
|
|
413
|
+
output?: OutputOptions;
|
|
414
|
+
routing?: {
|
|
415
|
+
strategy?: LocaleStrategy[];
|
|
416
|
+
routeStrategies?: {
|
|
417
|
+
[pattern: string]: LocaleStrategy[];
|
|
418
|
+
};
|
|
419
|
+
url?: UrlStrategy;
|
|
420
|
+
redirectRoot?: boolean;
|
|
421
|
+
propagate?: "header" | false;
|
|
422
|
+
switch?: "in-place" | "navigate";
|
|
423
|
+
cookie?: {
|
|
424
|
+
name?: string;
|
|
425
|
+
maxAge?: number;
|
|
426
|
+
};
|
|
427
|
+
/**
|
|
428
|
+
* The path the app's pages live under, as the URL codec reads it
|
|
429
|
+
* (`/de/pricing` under `/` names German). Default: Vite's `base`. Set it
|
|
430
|
+
* where Vite's base is an asset prefix instead (Nuxt: `app.baseURL`,
|
|
431
|
+
* while Vite's base is `/_nuxt/` in dev). null is the default.
|
|
432
|
+
*/
|
|
433
|
+
base?: string | null;
|
|
434
|
+
/**
|
|
435
|
+
* Localized paths: route path → locale → that locale's path, e.g.
|
|
436
|
+
* `{ "/about": { de: "/ueber-uns" } }` puts the German page at
|
|
437
|
+
* `/de/ueber-uns` while the router still sees `/about`. Paths are
|
|
438
|
+
* base-free; a `*` segment stands for one segment and a final `**` for
|
|
439
|
+
* any number, and each translation keeps them in order
|
|
440
|
+
* (`{ "/blog/*": { de: "/artikel/*" } }`).
|
|
441
|
+
*/
|
|
442
|
+
paths?: {
|
|
443
|
+
[path: string]: {
|
|
444
|
+
[locale: string]: string;
|
|
445
|
+
};
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
448
|
+
* Domain routing: host → the locale it serves, e.g.
|
|
449
|
+
* `{ "example.com": "en", "example.de": "de" }`. A key is a host
|
|
450
|
+
* (`https` assumed) or an origin (`http://localhost:5173`); a locale's
|
|
451
|
+
* first host is where links to it go. Every locale needs a host, and
|
|
452
|
+
* `url` stays `prefix_except_default`: on a listed host its locale is
|
|
453
|
+
* unprefixed, on any other host (dev servers, previews) the prefixes
|
|
454
|
+
* apply. The hosts are an allowlist: links and redirects never name
|
|
455
|
+
* another.
|
|
456
|
+
*/
|
|
457
|
+
domains?: {
|
|
458
|
+
[host: string]: string;
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
ssr?: {
|
|
462
|
+
timeZone?: string;
|
|
463
|
+
timeZoneFrom?: {
|
|
464
|
+
[pattern: string]: "config" | "request";
|
|
465
|
+
};
|
|
466
|
+
/**
|
|
467
|
+
* `"bundles"` (default): the page's client bundles are inlined into its
|
|
468
|
+
* SSR payload. `"preload"`: the payload names them and the page gets one
|
|
469
|
+
* `<link rel="preload" as="fetch" crossorigin>` per bundle instead, which
|
|
470
|
+
* the client runtime's fetch takes over, so bundles cache across pages.
|
|
471
|
+
*/
|
|
472
|
+
payload?: "bundles" | "preload";
|
|
473
|
+
/**
|
|
474
|
+
* Where a Vite-built server reads its catalogs. `"modules"`: lazy JSON
|
|
475
|
+
* modules in the server bundle. `"assets"`: files in the client output
|
|
476
|
+
* (`vi18n/<v>/<locale>/`), read through the Workers static-assets binding
|
|
477
|
+
* `env.ASSETS`, at most `maxLoadedLocales` locales loaded. `"auto"`
|
|
478
|
+
* (default): `"assets"` in a server environment that targets workerd
|
|
479
|
+
* (its resolve conditions include `workerd`, as @cloudflare/vite-plugin's
|
|
480
|
+
* do) of a build with a client entry, `"modules"` everywhere else.
|
|
481
|
+
*/
|
|
482
|
+
catalogs?: "auto" | "modules" | "assets";
|
|
483
|
+
/**
|
|
484
|
+
* With catalogs read from static assets: how many locales a server
|
|
485
|
+
* instance keeps loaded, the source locale included; the least recently
|
|
486
|
+
* used beyond it is dropped and read again when a request needs it.
|
|
487
|
+
* Default 8.
|
|
488
|
+
*/
|
|
489
|
+
maxLoadedLocales?: number;
|
|
490
|
+
normalizeSpaces?: boolean;
|
|
491
|
+
};
|
|
492
|
+
ai?: {
|
|
493
|
+
/** `"gemini"` (default) or a provider object: `openaiCompatible({ … })` or a custom one. */
|
|
494
|
+
provider?: "gemini" | TranslationProvider;
|
|
495
|
+
model?: string;
|
|
496
|
+
/**
|
|
497
|
+
* What AI never translates: configured locales, message ids, and globs
|
|
498
|
+
* (with `/` or `*`) over the config-relative files that use a message.
|
|
499
|
+
*/
|
|
500
|
+
exclude?: string[];
|
|
501
|
+
/**
|
|
502
|
+
* Required translations of source terms per locale (a language such as
|
|
503
|
+
* `de` covers `de-CH`): `{ workspace: { de: "Arbeitsbereich" } }`.
|
|
504
|
+
*/
|
|
505
|
+
glossary?: {
|
|
506
|
+
[term: string]: {
|
|
507
|
+
[locale: string]: string;
|
|
508
|
+
};
|
|
509
|
+
};
|
|
510
|
+
/** Names copied unchanged into every locale, e.g. `["Tidepool", "Wi-Fi"]`. */
|
|
511
|
+
doNotTranslate?: string[];
|
|
512
|
+
/** Tone and formality per locale, e.g. `{ de: "informal (du)" }`. */
|
|
513
|
+
tone?: {
|
|
514
|
+
[locale: string]: string;
|
|
515
|
+
};
|
|
516
|
+
/** Product description for the stable system prompt prefix. */
|
|
517
|
+
description?: string;
|
|
518
|
+
/** Environment variable holding the key. Default `GEMINI_API_KEY`. */
|
|
519
|
+
apiKeyEnv?: string;
|
|
520
|
+
/** Items per request, 40–80. Default 60. */
|
|
521
|
+
batchSize?: number;
|
|
522
|
+
/** Most requests in flight; halved on rate limits and regained gradually. Default 4. */
|
|
523
|
+
concurrency?: number;
|
|
524
|
+
/**
|
|
525
|
+
* P2: in `vite dev`, translate new messages in the background (debounced,
|
|
526
|
+
* off the transform path) and write them as `ai` entries. Default false.
|
|
527
|
+
*/
|
|
528
|
+
dev?: boolean;
|
|
529
|
+
};
|
|
530
|
+
/**
|
|
531
|
+
* Global rich-text tag handlers (PLAN §5.16): the element a message tag
|
|
532
|
+
* renders as when a call passes no handler of its own, in `richHtml()`
|
|
533
|
+
* and, in React, Preact and Vue, in `rich()`.
|
|
534
|
+
*/
|
|
535
|
+
defaults?: {
|
|
536
|
+
tags?: {
|
|
537
|
+
[tag: string]: TagDefault;
|
|
538
|
+
};
|
|
539
|
+
};
|
|
540
|
+
/**
|
|
541
|
+
* `vite dev` only: Alt+click on text opens the in-context editor, which
|
|
542
|
+
* writes translations into the catalogs (INTERNALS §2.18). Builds never
|
|
543
|
+
* carry it. Default `false`.
|
|
544
|
+
*/
|
|
545
|
+
devtools?: boolean;
|
|
546
|
+
/** `true` sets every rule to `"error"`. */
|
|
547
|
+
strict?: boolean | {
|
|
548
|
+
missing?: Level;
|
|
549
|
+
invalid?: Level;
|
|
550
|
+
moduleScope?: Level;
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
/** `output.*`: settings that matter to the build alone, also accepted inline by `vi18n({ output })`. */
|
|
554
|
+
interface OutputOptions {
|
|
555
|
+
split?: {
|
|
556
|
+
shared?: "per-set" | "single";
|
|
557
|
+
/** Source-locale bytes below which a set shared by several roots is duplicated. */
|
|
558
|
+
dupBelow?: number;
|
|
559
|
+
/** `s.*` bundles smaller than this coalesce into `shared`. */
|
|
560
|
+
minBytes?: number;
|
|
561
|
+
/** Cap on `s.*` bundles per root (spike S4); extra sets coalesce into `shared`. Default: no cap. */
|
|
562
|
+
maxBundlesPerRoot?: number | null;
|
|
563
|
+
};
|
|
564
|
+
guard?: "auto" | "always" | "off";
|
|
565
|
+
/** Stable URL outside `assetsDir`, relative to `base`, with `{locale}`. */
|
|
566
|
+
manifestPath?: string;
|
|
567
|
+
/** `"module"` puts the manifest into the runtime chunk (build-time `ssr:false` shells). */
|
|
568
|
+
manifest?: "data" | "module";
|
|
569
|
+
/** Globs on facade module ids that act as `base` entries in SSR builds. */
|
|
570
|
+
baseEntries?: string[];
|
|
571
|
+
/**
|
|
572
|
+
* Bundles as JSON arrays of messages, mapped to ids by position through one
|
|
573
|
+
* `ids.<v>.json` per build version that every locale shares. Default false.
|
|
574
|
+
*/
|
|
575
|
+
compactIds?: boolean;
|
|
576
|
+
/**
|
|
577
|
+
* One client build per locale with its translations inlined into the
|
|
578
|
+
* JavaScript (static SPAs): no bundle fetches, and switching locale loads
|
|
579
|
+
* the other locale's build. Default false.
|
|
580
|
+
*/
|
|
581
|
+
perLocale?: boolean;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* The validated config with every default applied. Paths are absolute;
|
|
585
|
+
* `catalogs.path` keeps its `{locale}` placeholder.
|
|
586
|
+
*/
|
|
587
|
+
interface ResolvedConfig {
|
|
588
|
+
/** Directory of `vi18n.config.ts`, or the Vite root / cwd when there is none. */
|
|
589
|
+
root: string;
|
|
590
|
+
/** Absolute path of the config file; null in zero-config mode. */
|
|
591
|
+
configFile: string | null;
|
|
592
|
+
sourceLocale: string;
|
|
593
|
+
locales: string[];
|
|
594
|
+
pseudoLocales: PseudoLocale[];
|
|
595
|
+
fallbacks: {
|
|
596
|
+
[locale: string]: string[];
|
|
597
|
+
};
|
|
598
|
+
project: {
|
|
599
|
+
include: string[];
|
|
600
|
+
extensions: string[];
|
|
601
|
+
exclude: string[];
|
|
602
|
+
};
|
|
603
|
+
extraction: {
|
|
604
|
+
importSources: string[];
|
|
605
|
+
aliases: string[];
|
|
606
|
+
globals: string[];
|
|
607
|
+
keep: string[];
|
|
608
|
+
dependencies: string[];
|
|
609
|
+
};
|
|
610
|
+
ids: {
|
|
611
|
+
length: number;
|
|
612
|
+
};
|
|
613
|
+
catalogs: {
|
|
614
|
+
format: "po" | "json";
|
|
615
|
+
path: string;
|
|
616
|
+
msgid: "source" | "id";
|
|
617
|
+
icuFlag: boolean;
|
|
618
|
+
};
|
|
619
|
+
output: {
|
|
620
|
+
split: {
|
|
621
|
+
shared: "per-set" | "single";
|
|
622
|
+
dupBelow: number;
|
|
623
|
+
minBytes: number;
|
|
624
|
+
maxBundlesPerRoot: number | null;
|
|
625
|
+
};
|
|
626
|
+
guard: "auto" | "always" | "off";
|
|
627
|
+
manifestPath: string;
|
|
628
|
+
manifest: "data" | "module";
|
|
629
|
+
baseEntries: string[];
|
|
630
|
+
compactIds: boolean;
|
|
631
|
+
perLocale: boolean;
|
|
632
|
+
};
|
|
633
|
+
routing: {
|
|
634
|
+
strategy: LocaleStrategy[];
|
|
635
|
+
routeStrategies: {
|
|
636
|
+
[pattern: string]: LocaleStrategy[];
|
|
637
|
+
};
|
|
638
|
+
url: UrlStrategy;
|
|
639
|
+
redirectRoot: boolean;
|
|
640
|
+
propagate: "header" | false;
|
|
641
|
+
switch: "in-place" | "navigate";
|
|
642
|
+
cookie: {
|
|
643
|
+
name: string;
|
|
644
|
+
maxAge: number;
|
|
645
|
+
};
|
|
646
|
+
/** `routing.base`; null: the environment's Vite `base`. */
|
|
647
|
+
base: string | null;
|
|
648
|
+
paths: {
|
|
649
|
+
[path: string]: {
|
|
650
|
+
[locale: string]: string;
|
|
651
|
+
};
|
|
652
|
+
};
|
|
653
|
+
/** Keys in origin form: `https://example.de`, `http://localhost:5173`. */
|
|
654
|
+
domains: {
|
|
655
|
+
[origin: string]: string;
|
|
656
|
+
};
|
|
657
|
+
};
|
|
658
|
+
ssr: {
|
|
659
|
+
timeZone: string;
|
|
660
|
+
timeZoneFrom: {
|
|
661
|
+
[pattern: string]: "config" | "request";
|
|
662
|
+
};
|
|
663
|
+
payload: "bundles" | "preload";
|
|
664
|
+
catalogs: "auto" | "modules" | "assets";
|
|
665
|
+
maxLoadedLocales: number;
|
|
666
|
+
normalizeSpaces: boolean;
|
|
667
|
+
};
|
|
668
|
+
ai: {
|
|
669
|
+
provider: "gemini" | TranslationProvider;
|
|
670
|
+
model: string;
|
|
671
|
+
exclude: string[];
|
|
672
|
+
glossary: {
|
|
673
|
+
[term: string]: {
|
|
674
|
+
[locale: string]: string;
|
|
675
|
+
};
|
|
676
|
+
};
|
|
677
|
+
doNotTranslate: string[];
|
|
678
|
+
tone: {
|
|
679
|
+
[locale: string]: string;
|
|
680
|
+
};
|
|
681
|
+
description: string | null;
|
|
682
|
+
apiKeyEnv: string;
|
|
683
|
+
batchSize: number;
|
|
684
|
+
concurrency: number;
|
|
685
|
+
dev: boolean;
|
|
686
|
+
};
|
|
687
|
+
defaults: {
|
|
688
|
+
tags: {
|
|
689
|
+
[tag: string]: TagDefault;
|
|
690
|
+
};
|
|
691
|
+
};
|
|
692
|
+
devtools: boolean;
|
|
693
|
+
strict: {
|
|
694
|
+
missing: Level;
|
|
695
|
+
invalid: Level;
|
|
696
|
+
moduleScope: Level;
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
/** A `defaults.tags` entry: an HTML element name, or the element with fixed attributes. */
|
|
700
|
+
type TagDefault = string | {
|
|
701
|
+
element: string;
|
|
702
|
+
attributes?: {
|
|
703
|
+
[name: string]: string;
|
|
704
|
+
};
|
|
705
|
+
};
|
|
706
|
+
//#endregion
|
|
707
|
+
export { MessageOccurrence as _, Vi18nConfig as a, OpenAICompatibleOptions as c, ProviderResponse as d, Tier as f, MessageCodec as g, Diagnostic as h, ResolvedConfig as i, ProviderOptions as l, TranslationProvider as m, OutputOptions as n, AiItem as o, TranslateOptions as p, PseudoLocale as r, BatchOptions as s, Level as t, ProviderRequest as u, LocaleStrategy as v, UrlStrategy as y };
|