@the-i18n-kit/cli 4.9.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 +368 -0
- package/dist/_shared-Dv1EW2gy.js +248 -0
- package/dist/_shared-Dv1EW2gy.js.map +1 -0
- package/dist/add-BvXrJkqZ.js +40 -0
- package/dist/add-BvXrJkqZ.js.map +1 -0
- package/dist/bin-Cs-dvpEC.d.ts +1 -0
- package/dist/bin.js +11 -0
- package/dist/bin.js.map +1 -0
- package/dist/check-9dcNfHtC.js +49 -0
- package/dist/check-9dcNfHtC.js.map +1 -0
- package/dist/cli-CiX4llY1.js +82 -0
- package/dist/cli-CiX4llY1.js.map +1 -0
- package/dist/config/framework/stubs/next-intl-routing-DEwC7Bbk.d.ts +19 -0
- package/dist/config/framework/stubs/next-intl-routing-DEwC7Bbk.d.ts.map +1 -0
- package/dist/config/framework/stubs/next-intl-routing.js +22 -0
- package/dist/config/framework/stubs/next-intl-routing.js.map +1 -0
- package/dist/config/framework/stubs/unplugin-vue-i18n-D9yaDzRk.d.ts +25 -0
- package/dist/config/framework/stubs/unplugin-vue-i18n-D9yaDzRk.d.ts.map +1 -0
- package/dist/config/framework/stubs/unplugin-vue-i18n.js +26 -0
- package/dist/config/framework/stubs/unplugin-vue-i18n.js.map +1 -0
- package/dist/define-config-4ubtfvUy.js +14 -0
- package/dist/define-config-4ubtfvUy.js.map +1 -0
- package/dist/define-config-Dhg13592.d.ts +142 -0
- package/dist/define-config-Dhg13592.d.ts.map +1 -0
- package/dist/define-config-lQrIpPSK.d.ts +2 -0
- package/dist/define-config.d.ts +1 -0
- package/dist/define-config.js +2 -0
- package/dist/detect-Dr2skxeL.js +17 -0
- package/dist/detect-Dr2skxeL.js.map +1 -0
- package/dist/empty-p0wct8Hk.js +36 -0
- package/dist/empty-p0wct8Hk.js.map +1 -0
- package/dist/errors-coI1dhw1.js +33 -0
- package/dist/errors-coI1dhw1.js.map +1 -0
- package/dist/find-duplicates-DuI8niF7.js +31 -0
- package/dist/find-duplicates-DuI8niF7.js.map +1 -0
- package/dist/get-BskDC2wT.js +41 -0
- package/dist/get-BskDC2wT.js.map +1 -0
- package/dist/index-BtSA6-iT.d.ts +1130 -0
- package/dist/index-BtSA6-iT.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/init-D7r6iX3q.js +33 -0
- package/dist/init-D7r6iX3q.js.map +1 -0
- package/dist/list-dirs-BHk38JXZ.js +17 -0
- package/dist/list-dirs-BHk38JXZ.js.map +1 -0
- package/dist/missing-0gSZKTgt.js +51 -0
- package/dist/missing-0gSZKTgt.js.map +1 -0
- package/dist/operations-BCJd7in3.js +6464 -0
- package/dist/operations-BCJd7in3.js.map +1 -0
- package/dist/php-reader-DcgOAhTw.js +2 -0
- package/dist/php-reader-DuZ0Hyl_.js +32 -0
- package/dist/php-reader-DuZ0Hyl_.js.map +1 -0
- package/dist/providers-BAwPjeCy.js +482 -0
- package/dist/providers-BAwPjeCy.js.map +1 -0
- package/dist/remove-DR_mRiMA.js +41 -0
- package/dist/remove-DR_mRiMA.js.map +1 -0
- package/dist/remove-orphans-CcA3XQHJ.js +57 -0
- package/dist/remove-orphans-CcA3XQHJ.js.map +1 -0
- package/dist/rename-CWLfThC1.js +45 -0
- package/dist/rename-CWLfThC1.js.map +1 -0
- package/dist/scaffold-BahXKbo9.js +39 -0
- package/dist/scaffold-BahXKbo9.js.map +1 -0
- package/dist/scan-CTxs3kl7.js +31 -0
- package/dist/scan-CTxs3kl7.js.map +1 -0
- package/dist/search-BonEgmSt.js +49 -0
- package/dist/search-BonEgmSt.js.map +1 -0
- package/dist/status-C_5Khw14.js +45 -0
- package/dist/status-C_5Khw14.js.map +1 -0
- package/dist/stdout-guard-sJHFWVem.js +20 -0
- package/dist/stdout-guard-sJHFWVem.js.map +1 -0
- package/dist/translate-CnXvBi5O.js +92 -0
- package/dist/translate-CnXvBi5O.js.map +1 -0
- package/dist/translate-key-DwO9XZMc.js +73 -0
- package/dist/translate-key-DwO9XZMc.js.map +1 -0
- package/dist/update-HR8MvPlI.js +40 -0
- package/dist/update-HR8MvPlI.js.map +1 -0
- package/dist/write-CAD9xQDy.js +47 -0
- package/dist/write-CAD9xQDy.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,1130 @@
|
|
|
1
|
+
import { a as LocaleDir, i as LocaleDefinition, n as defineI18nKitConfig, o as ProjectConfig, r as I18nConfig, t as I18nKitConfig } from "./define-config-Dhg13592.js";
|
|
2
|
+
|
|
3
|
+
//#region src/core/types.d.ts
|
|
4
|
+
|
|
5
|
+
interface LocaleDirInfo {
|
|
6
|
+
layer: string;
|
|
7
|
+
path: string;
|
|
8
|
+
aliasOf?: string;
|
|
9
|
+
fileCount: number;
|
|
10
|
+
topLevelKeys?: string[];
|
|
11
|
+
namespaces?: string[];
|
|
12
|
+
}
|
|
13
|
+
interface MutationPreview {
|
|
14
|
+
locale: string;
|
|
15
|
+
key: string;
|
|
16
|
+
value: string;
|
|
17
|
+
}
|
|
18
|
+
interface PlaceholderValidationIssue {
|
|
19
|
+
locale: string;
|
|
20
|
+
key: string;
|
|
21
|
+
missing: string[];
|
|
22
|
+
extra: string[];
|
|
23
|
+
/** What failed: placeholder set mismatch (default) or vue-i18n plural
|
|
24
|
+
* variant-count mismatch. Optional for backwards compatibility. */
|
|
25
|
+
kind?: 'placeholder' | 'plural-count';
|
|
26
|
+
/** Present for kind 'plural-count': variant counts of source and target. */
|
|
27
|
+
sourceVariants?: number;
|
|
28
|
+
targetVariants?: number;
|
|
29
|
+
}
|
|
30
|
+
interface PlaceholderValidationResult {
|
|
31
|
+
ok: boolean;
|
|
32
|
+
placeholders: string[];
|
|
33
|
+
errors: PlaceholderValidationIssue[];
|
|
34
|
+
}
|
|
35
|
+
interface LocaleRefInfo {
|
|
36
|
+
code: string;
|
|
37
|
+
language?: string;
|
|
38
|
+
file?: string;
|
|
39
|
+
name?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A locale ref in the request that matched no known locale. Its values were
|
|
43
|
+
* not written; the keys still appear in `written` because other locales
|
|
44
|
+
* succeeded, so this field is the only signal the write did less than asked.
|
|
45
|
+
*/
|
|
46
|
+
interface UnresolvedLocaleRef {
|
|
47
|
+
ref: string;
|
|
48
|
+
/** Keys whose value for this ref was dropped. */
|
|
49
|
+
keys: string[];
|
|
50
|
+
/** "Did you mean …?", when a near match exists. */
|
|
51
|
+
suggestion?: string;
|
|
52
|
+
}
|
|
53
|
+
interface MutationResult {
|
|
54
|
+
applied: string[];
|
|
55
|
+
skipped: string[];
|
|
56
|
+
warnings: string[];
|
|
57
|
+
filesWritten: number;
|
|
58
|
+
preview?: MutationPreview[];
|
|
59
|
+
placeholderValidation?: PlaceholderValidationResult;
|
|
60
|
+
/** Present only when a ref resolved to nothing. */
|
|
61
|
+
unresolvedLocales?: UnresolvedLocaleRef[];
|
|
62
|
+
/** Present only when a ref matched several locales and precedence picked one. */
|
|
63
|
+
ambiguousLocales?: LocaleRefAmbiguity[];
|
|
64
|
+
}
|
|
65
|
+
interface AddTranslationsResult {
|
|
66
|
+
/** Present when dryRun=true */
|
|
67
|
+
dryRun?: boolean;
|
|
68
|
+
wouldAdd?: MutationPreview[];
|
|
69
|
+
/** Present when dryRun=false */
|
|
70
|
+
added?: string[];
|
|
71
|
+
skipped: string[];
|
|
72
|
+
filesWritten?: number;
|
|
73
|
+
warnings?: string[];
|
|
74
|
+
/** Present only when a locale ref resolved to nothing — see UnresolvedLocaleRef. */
|
|
75
|
+
unresolvedLocales?: UnresolvedLocaleRef[];
|
|
76
|
+
/** Present only when a locale ref matched several locales. */
|
|
77
|
+
ambiguousLocales?: LocaleRefAmbiguity[];
|
|
78
|
+
placeholderValidation?: PlaceholderValidationResult;
|
|
79
|
+
summary?: {
|
|
80
|
+
keysToAdd: number;
|
|
81
|
+
keysSkipped: number;
|
|
82
|
+
message: string;
|
|
83
|
+
};
|
|
84
|
+
skippedKeys?: string[];
|
|
85
|
+
}
|
|
86
|
+
interface WriteTranslationsResult {
|
|
87
|
+
/** Present when dryRun=true */
|
|
88
|
+
dryRun?: boolean;
|
|
89
|
+
wouldWrite?: MutationPreview[];
|
|
90
|
+
/** Present when dryRun=false */
|
|
91
|
+
written?: string[];
|
|
92
|
+
skipped: string[];
|
|
93
|
+
filesWritten?: number;
|
|
94
|
+
warnings?: string[];
|
|
95
|
+
placeholderValidation?: PlaceholderValidationResult;
|
|
96
|
+
/** Present only when a locale ref resolved to nothing — see UnresolvedLocaleRef. */
|
|
97
|
+
unresolvedLocales?: UnresolvedLocaleRef[];
|
|
98
|
+
/** Present only when a locale ref matched several locales. */
|
|
99
|
+
ambiguousLocales?: LocaleRefAmbiguity[];
|
|
100
|
+
summary?: {
|
|
101
|
+
keysWritten: number;
|
|
102
|
+
keysSkipped: number;
|
|
103
|
+
message: string;
|
|
104
|
+
};
|
|
105
|
+
skippedKeys?: string[];
|
|
106
|
+
}
|
|
107
|
+
interface UpdateTranslationsResult {
|
|
108
|
+
/** Present when dryRun=true */
|
|
109
|
+
dryRun?: boolean;
|
|
110
|
+
wouldUpdate?: MutationPreview[];
|
|
111
|
+
/** Present when dryRun=false */
|
|
112
|
+
updated?: string[];
|
|
113
|
+
skipped: string[];
|
|
114
|
+
filesWritten?: number;
|
|
115
|
+
/** Present only when a locale ref resolved to nothing — see UnresolvedLocaleRef. */
|
|
116
|
+
unresolvedLocales?: UnresolvedLocaleRef[];
|
|
117
|
+
/** Present only when a locale ref matched several locales. */
|
|
118
|
+
ambiguousLocales?: LocaleRefAmbiguity[];
|
|
119
|
+
placeholderValidation?: PlaceholderValidationResult;
|
|
120
|
+
summary?: {
|
|
121
|
+
keysToUpdate: number;
|
|
122
|
+
keysSkipped: number;
|
|
123
|
+
message: string;
|
|
124
|
+
};
|
|
125
|
+
skippedKeys?: string[];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The config `init` emits. Only fields the matched adapter cannot derive:
|
|
129
|
+
* writing a copy of what the framework already states creates a second source
|
|
130
|
+
* of truth that drifts silently (#305). The generic path is the exception —
|
|
131
|
+
* without localeDirs and defaultLocale nothing resolves at all.
|
|
132
|
+
*/
|
|
133
|
+
interface GeneratedProjectConfig {
|
|
134
|
+
$schema: string;
|
|
135
|
+
context: string;
|
|
136
|
+
glossary: Record<string, string>;
|
|
137
|
+
translationPrompt: string;
|
|
138
|
+
localeNotes: Record<string, string>;
|
|
139
|
+
/** Matches localeDirEntrySchema: a bare path, or a path bound to a layer. */
|
|
140
|
+
localeDirs?: Array<string | {
|
|
141
|
+
path: string;
|
|
142
|
+
layer: string;
|
|
143
|
+
}>;
|
|
144
|
+
defaultLocale?: string;
|
|
145
|
+
locales?: string[];
|
|
146
|
+
}
|
|
147
|
+
interface InitProjectConfigResult {
|
|
148
|
+
config: GeneratedProjectConfig;
|
|
149
|
+
detected: {
|
|
150
|
+
adapter: string;
|
|
151
|
+
label: string;
|
|
152
|
+
/** Detection score. 0 when nothing matched and generic was assumed. */
|
|
153
|
+
confidence: number;
|
|
154
|
+
/**
|
|
155
|
+
* Whether the matched adapter resolves locales, layers and the default
|
|
156
|
+
* locale from framework config. False only for the generic adapter, which
|
|
157
|
+
* cannot resolve without them written into `.i18n-mcp.json`. Independent
|
|
158
|
+
* of whether this run carried locale settings forward from an existing
|
|
159
|
+
* file under `--force`.
|
|
160
|
+
*/
|
|
161
|
+
derivesLocaleConfig: boolean;
|
|
162
|
+
/** Other adapters that also scored, best first. */
|
|
163
|
+
runnersUp?: Array<{
|
|
164
|
+
name: string;
|
|
165
|
+
confidence: number;
|
|
166
|
+
}>;
|
|
167
|
+
/** Present when init could not find anything to point the config at. */
|
|
168
|
+
note?: string;
|
|
169
|
+
};
|
|
170
|
+
/** Path relative to the project dir. */
|
|
171
|
+
configPath: string;
|
|
172
|
+
written: boolean;
|
|
173
|
+
overwritten: boolean;
|
|
174
|
+
}
|
|
175
|
+
interface MissingTranslationsResult {
|
|
176
|
+
/** Absent when the full report went to `reportFile` instead. */
|
|
177
|
+
missing?: Record<string, Record<string, string[]>>;
|
|
178
|
+
summary: {
|
|
179
|
+
referenceLocale: string | LocaleRefInfo;
|
|
180
|
+
targetLocales: Array<string | LocaleRefInfo>;
|
|
181
|
+
layersScanned: string[];
|
|
182
|
+
totalMissingKeys: number;
|
|
183
|
+
};
|
|
184
|
+
/** Present when reportOutput is configured */
|
|
185
|
+
reportFile?: string;
|
|
186
|
+
}
|
|
187
|
+
interface LocaleStatus extends LocaleRefInfo {
|
|
188
|
+
total: number;
|
|
189
|
+
translated: number;
|
|
190
|
+
missing: number;
|
|
191
|
+
/** Present but empty-string — scaffolded and never filled. */
|
|
192
|
+
empty: number;
|
|
193
|
+
completion: number;
|
|
194
|
+
/** Listed in protectedLocales: maintained by hand. */
|
|
195
|
+
protected?: true;
|
|
196
|
+
/** Protected locales are reported but kept out of the overall figure. */
|
|
197
|
+
excludedFromOverall?: true;
|
|
198
|
+
}
|
|
199
|
+
interface LayerStatus {
|
|
200
|
+
layer: string;
|
|
201
|
+
total: number;
|
|
202
|
+
translated: number;
|
|
203
|
+
missing: number;
|
|
204
|
+
empty: number;
|
|
205
|
+
completion: number;
|
|
206
|
+
}
|
|
207
|
+
interface TranslationStatusSummary {
|
|
208
|
+
referenceLocale: LocaleRefInfo;
|
|
209
|
+
layersScanned: string[];
|
|
210
|
+
localesChecked: number;
|
|
211
|
+
protectedLocales: string[];
|
|
212
|
+
totalKeys: number;
|
|
213
|
+
translatedKeys: number;
|
|
214
|
+
missingKeys: number;
|
|
215
|
+
emptyKeys: number;
|
|
216
|
+
/** Overall completion, protected locales excluded. Read by --fail-under. */
|
|
217
|
+
completionPercent: number;
|
|
218
|
+
}
|
|
219
|
+
interface TranslationStatusResult {
|
|
220
|
+
locales?: LocaleStatus[];
|
|
221
|
+
layers?: LayerStatus[];
|
|
222
|
+
summary: TranslationStatusSummary;
|
|
223
|
+
/** Present when the full breakdown went to a file instead. */
|
|
224
|
+
reportFile?: string;
|
|
225
|
+
}
|
|
226
|
+
interface EmptyTranslationsResult {
|
|
227
|
+
/** Absent when the full report went to `reportFile` instead. */
|
|
228
|
+
emptyKeys?: Record<string, Record<string, string[]>>;
|
|
229
|
+
summary: {
|
|
230
|
+
totalEmpty: number;
|
|
231
|
+
localesChecked: string[];
|
|
232
|
+
layersChecked: string[];
|
|
233
|
+
};
|
|
234
|
+
/** Present when reportOutput is configured */
|
|
235
|
+
reportFile?: string;
|
|
236
|
+
}
|
|
237
|
+
interface SearchMatch {
|
|
238
|
+
layer: string;
|
|
239
|
+
locale: string;
|
|
240
|
+
key: string;
|
|
241
|
+
value: unknown;
|
|
242
|
+
}
|
|
243
|
+
interface SearchTranslationsResult {
|
|
244
|
+
matches: SearchMatch[];
|
|
245
|
+
totalMatches: number;
|
|
246
|
+
}
|
|
247
|
+
interface RemoveTranslationsPreview {
|
|
248
|
+
locale: string;
|
|
249
|
+
key: string;
|
|
250
|
+
oldValue: unknown;
|
|
251
|
+
}
|
|
252
|
+
interface RemoveTranslationsResult {
|
|
253
|
+
/** Present when dryRun=true */
|
|
254
|
+
dryRun?: boolean;
|
|
255
|
+
wouldRemove?: RemoveTranslationsPreview[];
|
|
256
|
+
/** Present when dryRun=false */
|
|
257
|
+
removed?: string[];
|
|
258
|
+
removedPerLocale?: string[];
|
|
259
|
+
notFound?: string[];
|
|
260
|
+
filesWritten?: number;
|
|
261
|
+
summary?: {
|
|
262
|
+
keysFound: number;
|
|
263
|
+
message: string;
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
interface RenameTranslationKeyPreview {
|
|
267
|
+
locale: string;
|
|
268
|
+
oldKey: string;
|
|
269
|
+
newKey: string;
|
|
270
|
+
value: unknown;
|
|
271
|
+
}
|
|
272
|
+
interface RenameTranslationKeyResult {
|
|
273
|
+
/** Present when dryRun=true */
|
|
274
|
+
dryRun?: boolean;
|
|
275
|
+
wouldRename?: RenameTranslationKeyPreview[];
|
|
276
|
+
/** Present when dryRun=false */
|
|
277
|
+
renamed?: string[];
|
|
278
|
+
filesWritten?: number;
|
|
279
|
+
oldKey?: string;
|
|
280
|
+
newKey?: string;
|
|
281
|
+
notFoundInLocales?: string[];
|
|
282
|
+
conflictsInLocales?: string[];
|
|
283
|
+
skippedDueToConflict?: string[];
|
|
284
|
+
summary?: {
|
|
285
|
+
localesAffected: number;
|
|
286
|
+
message: string;
|
|
287
|
+
warning?: string;
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/** How a translate run was (or would be) executed. */
|
|
291
|
+
type TranslateMode = 'provider' | 'agent' | 'dry-run';
|
|
292
|
+
/** Why a key could not be translated. */
|
|
293
|
+
type TranslateFailReason = 'provider-error' | 'omitted-by-model' | 'placeholder-mismatch' | 'plural-mismatch' | 'write-error' | 'truncated';
|
|
294
|
+
/** Why a key or locale was intentionally not attempted. */
|
|
295
|
+
type TranslateSkipReason = 'no-provider' | 'already-translated' | 'protected-locale';
|
|
296
|
+
interface TranslateMissingLocaleResult {
|
|
297
|
+
mode: TranslateMode;
|
|
298
|
+
/** Number of missing keys found for this locale. Always equals
|
|
299
|
+
* translated + wouldTranslate + failed + skipped. */
|
|
300
|
+
missing: number;
|
|
301
|
+
translated: string[];
|
|
302
|
+
/** Dry-run only: keys that would be translated. */
|
|
303
|
+
wouldTranslate?: string[];
|
|
304
|
+
failed: Array<{
|
|
305
|
+
key: string;
|
|
306
|
+
reason: TranslateFailReason;
|
|
307
|
+
}>;
|
|
308
|
+
skipped: Array<{
|
|
309
|
+
key: string;
|
|
310
|
+
reason: TranslateSkipReason;
|
|
311
|
+
}>;
|
|
312
|
+
batches?: number;
|
|
313
|
+
model?: string;
|
|
314
|
+
writeError?: string;
|
|
315
|
+
placeholderValidation?: PlaceholderValidationResult;
|
|
316
|
+
}
|
|
317
|
+
/** One locale's digest in compact mode: counts rather than key lists. */
|
|
318
|
+
interface TranslateMissingCompactEntry {
|
|
319
|
+
locale: string;
|
|
320
|
+
mode: TranslateMode;
|
|
321
|
+
missing: number;
|
|
322
|
+
translated: number;
|
|
323
|
+
failed: number;
|
|
324
|
+
skipped: number;
|
|
325
|
+
wouldTranslate?: number;
|
|
326
|
+
batches?: number;
|
|
327
|
+
model?: string;
|
|
328
|
+
writeError?: string;
|
|
329
|
+
}
|
|
330
|
+
interface TranslateMissingResult {
|
|
331
|
+
/** Absent in compact mode, which returns `summary.byLocale` instead. */
|
|
332
|
+
results?: Record<string, TranslateMissingLocaleResult>;
|
|
333
|
+
fallbackContexts?: Record<string, Record<string, unknown>>;
|
|
334
|
+
summary: {
|
|
335
|
+
/** Compact mode only: a per-locale digest in place of full `results`. */
|
|
336
|
+
byLocale?: TranslateMissingCompactEntry[];
|
|
337
|
+
mode: TranslateMode;
|
|
338
|
+
totalTranslated: number;
|
|
339
|
+
totalFailed: number;
|
|
340
|
+
totalSkipped: number;
|
|
341
|
+
totalWouldTranslate?: number;
|
|
342
|
+
layer: string;
|
|
343
|
+
referenceLocale: string | LocaleRefInfo;
|
|
344
|
+
targetLocales: Array<string | LocaleRefInfo>;
|
|
345
|
+
dryRun: boolean;
|
|
346
|
+
/** Surface-owned guidance (set by the CLI command or MCP tool, not the core). */
|
|
347
|
+
message?: string;
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Per-layer totals in the all-layers translate summary (`summary.byLayer`).
|
|
352
|
+
* Field names mirror the cross-layer summary totals so consumers parse both
|
|
353
|
+
* with the same accessors. `totalWouldTranslate` is always present (0 outside
|
|
354
|
+
* dry runs).
|
|
355
|
+
*/
|
|
356
|
+
/** Aggregated summary across every locale-backed layer. */
|
|
357
|
+
interface TranslateAllLayersSummary {
|
|
358
|
+
mode: TranslateMode;
|
|
359
|
+
totalTranslated: number;
|
|
360
|
+
totalFailed: number;
|
|
361
|
+
totalSkipped: number;
|
|
362
|
+
totalWouldTranslate?: number;
|
|
363
|
+
/** Layer names that were translated. */
|
|
364
|
+
layers: string[];
|
|
365
|
+
byLayer: TranslateLayerTotals[];
|
|
366
|
+
dryRun: boolean;
|
|
367
|
+
referenceLocale?: string | LocaleRefInfo;
|
|
368
|
+
targetLocales?: Array<string | LocaleRefInfo>;
|
|
369
|
+
/** Surface-owned guidance (set by the CLI command or MCP tool). */
|
|
370
|
+
message?: string;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* All-layers mode (`--layer` omitted): one result per layer plus an aggregated
|
|
374
|
+
* summary. Discriminate with `'layers' in result` — both members carry a
|
|
375
|
+
* `summary`, and both summaries carry `mode`, so mode checks need no narrowing.
|
|
376
|
+
*/
|
|
377
|
+
interface TranslateAllLayersResult {
|
|
378
|
+
layers: Record<string, TranslateMissingResult>;
|
|
379
|
+
summary: TranslateAllLayersSummary;
|
|
380
|
+
}
|
|
381
|
+
/** What translateMissing returns: depends on whether a layer was named. */
|
|
382
|
+
type TranslateMissingOutcome = TranslateMissingResult | TranslateAllLayersResult;
|
|
383
|
+
interface TranslateLayerTotals {
|
|
384
|
+
layer: string;
|
|
385
|
+
totalTranslated: number;
|
|
386
|
+
totalFailed: number;
|
|
387
|
+
totalSkipped: number;
|
|
388
|
+
totalWouldTranslate: number;
|
|
389
|
+
}
|
|
390
|
+
interface TranslateKeyLocaleIssue {
|
|
391
|
+
locale: string;
|
|
392
|
+
reason: TranslateFailReason | 'read-error';
|
|
393
|
+
detail?: string;
|
|
394
|
+
}
|
|
395
|
+
interface TranslateKeyResult {
|
|
396
|
+
key: string;
|
|
397
|
+
sourceLocale: LocaleRefInfo;
|
|
398
|
+
updatedSource: boolean;
|
|
399
|
+
mode: TranslateMode;
|
|
400
|
+
translated: string[];
|
|
401
|
+
/** Dry-run only: locales that would be translated. */
|
|
402
|
+
wouldTranslate?: string[];
|
|
403
|
+
skipped: Array<{
|
|
404
|
+
locale: string;
|
|
405
|
+
reason: TranslateSkipReason;
|
|
406
|
+
}>;
|
|
407
|
+
failed: TranslateKeyLocaleIssue[];
|
|
408
|
+
filesWritten: number;
|
|
409
|
+
dryRun: boolean;
|
|
410
|
+
model?: string;
|
|
411
|
+
placeholderValidation: PlaceholderValidationResult;
|
|
412
|
+
preview?: Record<string, string>;
|
|
413
|
+
fallbackContext?: Record<string, unknown>;
|
|
414
|
+
/** Surface-owned guidance (set by the CLI command or MCP tool, not the core). */
|
|
415
|
+
message?: string;
|
|
416
|
+
}
|
|
417
|
+
/** A key referenced only from apps outside its layer's consumption scope. */
|
|
418
|
+
interface MisplacedUsageRef {
|
|
419
|
+
key: string;
|
|
420
|
+
/** Layer the key is defined in. */
|
|
421
|
+
layer: string;
|
|
422
|
+
/** Out-of-scope scan units (apps or layers) where the key was found. */
|
|
423
|
+
usingApps: string[];
|
|
424
|
+
}
|
|
425
|
+
interface DynamicKeyRef {
|
|
426
|
+
expression: string;
|
|
427
|
+
/** Absent for context-free bare candidates, which have no single call site. */
|
|
428
|
+
file?: string;
|
|
429
|
+
line?: number;
|
|
430
|
+
}
|
|
431
|
+
interface UnresolvedKeyWarningRef {
|
|
432
|
+
expression: string;
|
|
433
|
+
file: string;
|
|
434
|
+
line: number;
|
|
435
|
+
callee: string;
|
|
436
|
+
suggestedIgnorePattern?: string;
|
|
437
|
+
}
|
|
438
|
+
interface FindOrphanKeysResult {
|
|
439
|
+
/** Absent when the full report went to `reportFile` instead. */
|
|
440
|
+
orphanKeys?: Record<string, string[]>;
|
|
441
|
+
uncertainKeys?: Record<string, string[]>;
|
|
442
|
+
/** Keys used only from apps that do not consume the owning layer. */
|
|
443
|
+
misplacedUsages?: MisplacedUsageRef[];
|
|
444
|
+
misplacedUsageNote?: string;
|
|
445
|
+
summary: {
|
|
446
|
+
totalKeys: number;
|
|
447
|
+
orphanCount: number;
|
|
448
|
+
uncertainCount?: number;
|
|
449
|
+
misplacedCount?: number;
|
|
450
|
+
dynamicMatchedCount?: number;
|
|
451
|
+
ignoredCount?: number;
|
|
452
|
+
usedCount?: number;
|
|
453
|
+
filesScanned: number;
|
|
454
|
+
layersChecked?: string[];
|
|
455
|
+
dirsScanned?: string[];
|
|
456
|
+
scanScope?: Record<string, string[]>;
|
|
457
|
+
locale?: string;
|
|
458
|
+
message?: string;
|
|
459
|
+
};
|
|
460
|
+
dynamicKeyWarning?: string;
|
|
461
|
+
dynamicKeys?: DynamicKeyRef[];
|
|
462
|
+
unresolvedKeyWarnings?: UnresolvedKeyWarningRef[];
|
|
463
|
+
/** Present when reportOutput is configured */
|
|
464
|
+
reportFile?: string;
|
|
465
|
+
}
|
|
466
|
+
/** Where each requested key is referenced in source. */
|
|
467
|
+
interface CodeUsageResult {
|
|
468
|
+
/** Absent when the full report went to `reportFile` instead. */
|
|
469
|
+
usages?: Record<string, CodeUsageRef[]>;
|
|
470
|
+
/** Requested keys with no reference anywhere in the scanned source. */
|
|
471
|
+
notFoundInCode?: string[];
|
|
472
|
+
/** Dynamic expressions that could reach the requested keys. */
|
|
473
|
+
dynamicKeys?: DynamicKeyRef[];
|
|
474
|
+
summary: {
|
|
475
|
+
uniqueKeysFound: number;
|
|
476
|
+
totalReferences: number;
|
|
477
|
+
filesScanned: number;
|
|
478
|
+
dirsScanned?: string[];
|
|
479
|
+
message?: string;
|
|
480
|
+
};
|
|
481
|
+
/** Present when the full report went to a file instead. */
|
|
482
|
+
reportFile?: string;
|
|
483
|
+
}
|
|
484
|
+
interface CodeUsageRef {
|
|
485
|
+
file: string;
|
|
486
|
+
line: number;
|
|
487
|
+
callee: string;
|
|
488
|
+
}
|
|
489
|
+
interface ScanCodeUsageResult {
|
|
490
|
+
usages: Record<string, CodeUsageRef[]>;
|
|
491
|
+
summary: {
|
|
492
|
+
uniqueKeysFound: number;
|
|
493
|
+
totalReferences: number;
|
|
494
|
+
filesScanned: number;
|
|
495
|
+
dirsScanned: string[];
|
|
496
|
+
};
|
|
497
|
+
notFoundInCode?: string[];
|
|
498
|
+
dynamicKeys?: DynamicKeyRef[];
|
|
499
|
+
/** Present when reportOutput is configured */
|
|
500
|
+
reportFile?: string;
|
|
501
|
+
}
|
|
502
|
+
interface RemoveOrphanKeysResult {
|
|
503
|
+
orphanKeys?: Record<string, string[]>;
|
|
504
|
+
removed?: Record<string, string[]>;
|
|
505
|
+
uncertainKeys?: Record<string, string[]>;
|
|
506
|
+
misplacedUsages?: MisplacedUsageRef[];
|
|
507
|
+
misplacedUsageNote?: string;
|
|
508
|
+
summary: {
|
|
509
|
+
dryRun?: boolean;
|
|
510
|
+
totalKeys: number;
|
|
511
|
+
orphanCount?: number;
|
|
512
|
+
removedCount?: number;
|
|
513
|
+
uncertainCount?: number;
|
|
514
|
+
misplacedCount?: number;
|
|
515
|
+
dynamicMatchedCount?: number;
|
|
516
|
+
ignoredCount?: number;
|
|
517
|
+
usedCount?: number;
|
|
518
|
+
remainingCount?: number;
|
|
519
|
+
filesScanned?: number;
|
|
520
|
+
filesWritten?: number;
|
|
521
|
+
layersChecked?: string[];
|
|
522
|
+
dirsScanned?: string[];
|
|
523
|
+
scanScope?: Record<string, string[]>;
|
|
524
|
+
locale?: string;
|
|
525
|
+
message?: string;
|
|
526
|
+
};
|
|
527
|
+
dynamicKeyWarning?: string;
|
|
528
|
+
dynamicKeys?: DynamicKeyRef[];
|
|
529
|
+
unresolvedKeyWarnings?: UnresolvedKeyWarningRef[];
|
|
530
|
+
/** Present when reportOutput is configured */
|
|
531
|
+
reportFile?: string;
|
|
532
|
+
}
|
|
533
|
+
interface ScaffoldLocaleFileInfo {
|
|
534
|
+
locale: string;
|
|
535
|
+
layer: string;
|
|
536
|
+
file: string;
|
|
537
|
+
keys: number;
|
|
538
|
+
namespace?: string;
|
|
539
|
+
}
|
|
540
|
+
interface ScaffoldLocaleResult {
|
|
541
|
+
created: ScaffoldLocaleFileInfo[];
|
|
542
|
+
skipped: ScaffoldLocaleFileInfo[];
|
|
543
|
+
dryRun: boolean;
|
|
544
|
+
}
|
|
545
|
+
interface TranslateRequest {
|
|
546
|
+
systemPrompt: string;
|
|
547
|
+
userMessage: string;
|
|
548
|
+
maxTokens: number;
|
|
549
|
+
}
|
|
550
|
+
interface TranslateResponse {
|
|
551
|
+
text: string;
|
|
552
|
+
model: string;
|
|
553
|
+
/** True when the provider stopped early (finish/stop reason = token limit).
|
|
554
|
+
* The response text is incomplete and must not be parsed as a full batch. */
|
|
555
|
+
truncated?: boolean;
|
|
556
|
+
}
|
|
557
|
+
type TranslateFn = (opts: TranslateRequest) => Promise<TranslateResponse>;
|
|
558
|
+
type ProgressFn = (message: string) => Promise<void>;
|
|
559
|
+
//# sourceMappingURL=types.d.ts.map
|
|
560
|
+
//#endregion
|
|
561
|
+
//#region src/core/shared.d.ts
|
|
562
|
+
/** Fields a locale ref may match, in resolution precedence order. */
|
|
563
|
+
declare const LOCALE_MATCH_FIELDS: readonly ["code", "language", "file"];
|
|
564
|
+
type LocaleMatchField = (typeof LOCALE_MATCH_FIELDS)[number];
|
|
565
|
+
interface LocaleRefAmbiguity {
|
|
566
|
+
ref: string;
|
|
567
|
+
/** The field that matched more than one locale. */
|
|
568
|
+
matchedBy: LocaleMatchField;
|
|
569
|
+
/** Codes of every locale the ref matched, in config order. */
|
|
570
|
+
candidates: string[];
|
|
571
|
+
/** The one that was used — the first candidate. */
|
|
572
|
+
resolvedTo: string;
|
|
573
|
+
}
|
|
574
|
+
declare function findLocaleImpl(config: I18nConfig, localeRef: string): LocaleDefinition | undefined;
|
|
575
|
+
/**
|
|
576
|
+
* Resolve the reference locale for scan operations: the requested ref or the
|
|
577
|
+
* project default. Throws LOCALE_NOT_FOUND listing the available codes.
|
|
578
|
+
*/
|
|
579
|
+
//#endregion
|
|
580
|
+
//#region src/core/ops-translate.d.ts
|
|
581
|
+
/**
|
|
582
|
+
* Resolve the config's `protectedLocales` entries (any locale ref: code,
|
|
583
|
+
* language tag, or file name) against the known locales. Entries that do not
|
|
584
|
+
* match a known locale are ignored with a warning. Returns the resolved
|
|
585
|
+
* definitions, deduplicated by canonical code.
|
|
586
|
+
*/
|
|
587
|
+
declare function resolveProtectedLocales(config: I18nConfig): LocaleDefinition[];
|
|
588
|
+
/**
|
|
589
|
+
* Find keys missing in target locales and translate them.
|
|
590
|
+
*
|
|
591
|
+
* When translateFn is provided, uses it to translate via LLM.
|
|
592
|
+
* When translateFn is absent, returns fallback contexts for the agent.
|
|
593
|
+
*
|
|
594
|
+
* When `layer` is omitted, every canonical locale-backed layer is translated
|
|
595
|
+
* in one run and the results are aggregated (see translateMissingAllLayers).
|
|
596
|
+
*/
|
|
597
|
+
declare function translateMissing(opts: {
|
|
598
|
+
layer?: string;
|
|
599
|
+
referenceLocale?: string;
|
|
600
|
+
targetLocales?: string[];
|
|
601
|
+
locales?: string[];
|
|
602
|
+
keys?: string[];
|
|
603
|
+
batchSize?: number;
|
|
604
|
+
dryRun?: boolean;
|
|
605
|
+
compact?: boolean;
|
|
606
|
+
projectDir?: string;
|
|
607
|
+
translateFn?: TranslateFn;
|
|
608
|
+
progressFn?: ProgressFn;
|
|
609
|
+
/** Called once after the pre-scan with the computed total number of progress steps. */
|
|
610
|
+
onProgressTotal?: (total: number) => void;
|
|
611
|
+
}): Promise<TranslateMissingOutcome>;
|
|
612
|
+
/**
|
|
613
|
+
* Translate one key from a source locale into target locales. Unlike
|
|
614
|
+
* translate_missing, this can overwrite stale existing target values.
|
|
615
|
+
*/
|
|
616
|
+
declare function translateKey(opts: {
|
|
617
|
+
layer: string;
|
|
618
|
+
key: string;
|
|
619
|
+
sourceLocale: string;
|
|
620
|
+
sourceValue?: string;
|
|
621
|
+
targetLocales?: string[] | 'all';
|
|
622
|
+
overwrite?: boolean;
|
|
623
|
+
dryRun?: boolean;
|
|
624
|
+
includePreview?: boolean;
|
|
625
|
+
projectDir?: string;
|
|
626
|
+
translateFn?: TranslateFn;
|
|
627
|
+
}): Promise<TranslateKeyResult>;
|
|
628
|
+
//# sourceMappingURL=ops-translate.d.ts.map
|
|
629
|
+
//#endregion
|
|
630
|
+
//#region src/core/ops-read.d.ts
|
|
631
|
+
/**
|
|
632
|
+
* Detect the i18n configuration from the project, always bypassing the
|
|
633
|
+
* config cache (clears it first).
|
|
634
|
+
*/
|
|
635
|
+
declare function detectConfig(projectDir?: string): Promise<I18nConfig>;
|
|
636
|
+
/**
|
|
637
|
+
* List all i18n locale directories in the project, grouped by layer.
|
|
638
|
+
*/
|
|
639
|
+
declare function listLocaleDirs(projectDir?: string): Promise<LocaleDirInfo[]>;
|
|
640
|
+
/**
|
|
641
|
+
* Get translation values for given key paths from a specific locale and layer.
|
|
642
|
+
*/
|
|
643
|
+
declare function getTranslations(opts: {
|
|
644
|
+
layer: string;
|
|
645
|
+
locale: string;
|
|
646
|
+
keys: string[];
|
|
647
|
+
compact?: boolean;
|
|
648
|
+
projectDir?: string;
|
|
649
|
+
}): Promise<Record<string, Record<string, unknown>>>;
|
|
650
|
+
/**
|
|
651
|
+
* Find translation keys that exist in the reference locale but are missing in other locales.
|
|
652
|
+
*/
|
|
653
|
+
declare function getMissingTranslations(opts: {
|
|
654
|
+
layer?: string;
|
|
655
|
+
referenceLocale?: string;
|
|
656
|
+
targetLocales?: string[];
|
|
657
|
+
locales?: string[];
|
|
658
|
+
projectDir?: string;
|
|
659
|
+
outputFile?: string;
|
|
660
|
+
}): Promise<MissingTranslationsResult>;
|
|
661
|
+
/**
|
|
662
|
+
* Find translation keys that have empty string values in locale files.
|
|
663
|
+
*/
|
|
664
|
+
declare function findEmptyTranslations(opts: {
|
|
665
|
+
layer?: string;
|
|
666
|
+
locale?: string;
|
|
667
|
+
projectDir?: string;
|
|
668
|
+
outputFile?: string;
|
|
669
|
+
}): Promise<EmptyTranslationsResult>;
|
|
670
|
+
/**
|
|
671
|
+
* Search translation files by key pattern or value substring.
|
|
672
|
+
*/
|
|
673
|
+
declare function searchTranslations(opts: {
|
|
674
|
+
query: string;
|
|
675
|
+
searchIn?: 'keys' | 'values' | 'both';
|
|
676
|
+
layer?: string;
|
|
677
|
+
locale?: string;
|
|
678
|
+
projectDir?: string;
|
|
679
|
+
outputFile?: string;
|
|
680
|
+
}): Promise<{
|
|
681
|
+
matches: SearchMatch[];
|
|
682
|
+
totalMatches: number;
|
|
683
|
+
} | {
|
|
684
|
+
reportFile: string;
|
|
685
|
+
summary: {
|
|
686
|
+
totalMatches: number;
|
|
687
|
+
};
|
|
688
|
+
}>;
|
|
689
|
+
interface NamespaceNode {
|
|
690
|
+
keyCount: number;
|
|
691
|
+
children?: Record<string, NamespaceNode>;
|
|
692
|
+
}
|
|
693
|
+
interface ListNamespacesResult {
|
|
694
|
+
layers: Record<string, {
|
|
695
|
+
namespaces: Record<string, NamespaceNode>;
|
|
696
|
+
}>;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Build a prefix tree of all translation keys grouped by layer and namespace.
|
|
700
|
+
* Useful for agents to browse available keys without guesswork.
|
|
701
|
+
*/
|
|
702
|
+
declare function listNamespaces(opts: {
|
|
703
|
+
layer?: string;
|
|
704
|
+
locale?: string;
|
|
705
|
+
projectDir?: string;
|
|
706
|
+
}): Promise<ListNamespacesResult>;
|
|
707
|
+
//# sourceMappingURL=ops-read.d.ts.map
|
|
708
|
+
//#endregion
|
|
709
|
+
//#region src/core/ops-write.d.ts
|
|
710
|
+
/**
|
|
711
|
+
* Write translation keys to the specified layer with mode control.
|
|
712
|
+
*
|
|
713
|
+
* Mode:
|
|
714
|
+
* - 'upsert' (default): Adds new keys and updates existing ones. Never skips.
|
|
715
|
+
* - 'add': Only creates new keys, skipping existing ones.
|
|
716
|
+
* - 'update': Only modifies existing keys, skipping missing ones.
|
|
717
|
+
*/
|
|
718
|
+
declare function writeTranslations(opts: {
|
|
719
|
+
layer: string;
|
|
720
|
+
translations: Record<string, Record<string, string>>;
|
|
721
|
+
mode?: 'add' | 'update' | 'upsert';
|
|
722
|
+
dryRun?: boolean;
|
|
723
|
+
projectDir?: string;
|
|
724
|
+
}): Promise<WriteTranslationsResult>;
|
|
725
|
+
/**
|
|
726
|
+
* Add new translation keys to the specified layer.
|
|
727
|
+
*
|
|
728
|
+
* @deprecated Use writeTranslations with mode: 'add' instead.
|
|
729
|
+
*/
|
|
730
|
+
declare function addTranslations(opts: {
|
|
731
|
+
layer: string;
|
|
732
|
+
translations: Record<string, Record<string, string>>;
|
|
733
|
+
dryRun?: boolean;
|
|
734
|
+
projectDir?: string;
|
|
735
|
+
}): Promise<AddTranslationsResult>;
|
|
736
|
+
/**
|
|
737
|
+
* Update existing translation keys in the specified layer.
|
|
738
|
+
*
|
|
739
|
+
* @deprecated Use writeTranslations with mode: 'update' instead.
|
|
740
|
+
*/
|
|
741
|
+
declare function updateTranslations(opts: {
|
|
742
|
+
layer: string;
|
|
743
|
+
translations: Record<string, Record<string, string>>;
|
|
744
|
+
dryRun?: boolean;
|
|
745
|
+
projectDir?: string;
|
|
746
|
+
}): Promise<UpdateTranslationsResult>;
|
|
747
|
+
/**
|
|
748
|
+
* Remove one or more translation keys from ALL locale files in the specified layer.
|
|
749
|
+
*/
|
|
750
|
+
declare function removeTranslations(opts: {
|
|
751
|
+
layer: string;
|
|
752
|
+
keys: string[];
|
|
753
|
+
dryRun?: boolean;
|
|
754
|
+
projectDir?: string;
|
|
755
|
+
}): Promise<RemoveTranslationsResult>;
|
|
756
|
+
/**
|
|
757
|
+
* Rename/move a translation key across ALL locale files in a layer.
|
|
758
|
+
*/
|
|
759
|
+
declare function renameTranslationKey(opts: {
|
|
760
|
+
layer: string;
|
|
761
|
+
oldKey: string;
|
|
762
|
+
newKey: string;
|
|
763
|
+
dryRun?: boolean;
|
|
764
|
+
projectDir?: string;
|
|
765
|
+
}): Promise<RenameTranslationKeyResult>;
|
|
766
|
+
/**
|
|
767
|
+
* Create empty locale files for new languages.
|
|
768
|
+
*/
|
|
769
|
+
declare function scaffoldLocaleFiles(opts: {
|
|
770
|
+
locales?: string[];
|
|
771
|
+
layer?: string;
|
|
772
|
+
dryRun?: boolean;
|
|
773
|
+
projectDir?: string;
|
|
774
|
+
}): Promise<ScaffoldLocaleResult>;
|
|
775
|
+
//# sourceMappingURL=ops-write.d.ts.map
|
|
776
|
+
//#endregion
|
|
777
|
+
//#region src/core/ops-status.d.ts
|
|
778
|
+
/**
|
|
779
|
+
* Coverage for a project: per locale, per layer, and one overall figure.
|
|
780
|
+
*
|
|
781
|
+
* Protected locales are counted and reported but excluded from the overall
|
|
782
|
+
* percentage — they are maintained by hand, so counting their gaps as project
|
|
783
|
+
* debt makes a healthy project read as failing and moves a number nobody can
|
|
784
|
+
* act on.
|
|
785
|
+
*/
|
|
786
|
+
declare function getTranslationStatus(opts: {
|
|
787
|
+
layer?: string;
|
|
788
|
+
referenceLocale?: string;
|
|
789
|
+
projectDir?: string;
|
|
790
|
+
outputFile?: string;
|
|
791
|
+
}): Promise<TranslationStatusResult>;
|
|
792
|
+
//# sourceMappingURL=ops-status.d.ts.map
|
|
793
|
+
|
|
794
|
+
//#endregion
|
|
795
|
+
//#region src/core/ops-orphans.d.ts
|
|
796
|
+
/**
|
|
797
|
+
* Find translation keys that exist in locale files but are not referenced in source code.
|
|
798
|
+
*/
|
|
799
|
+
declare function findOrphanKeys(opts: {
|
|
800
|
+
layer?: string;
|
|
801
|
+
locale?: string;
|
|
802
|
+
/**
|
|
803
|
+
* Explicit scan roots — manual scope control. When set, all layers are
|
|
804
|
+
* checked against one combined usage set from these dirs (no per-layer
|
|
805
|
+
* scoping, no misplaced-usage detection). When absent, a scope-aware plan
|
|
806
|
+
* from the layer graph is used: each layer is checked against the apps
|
|
807
|
+
* that consume it.
|
|
808
|
+
*/
|
|
809
|
+
scanDirs?: string[];
|
|
810
|
+
excludeDirs?: string[];
|
|
811
|
+
projectDir?: string;
|
|
812
|
+
outputFile?: string;
|
|
813
|
+
}): Promise<FindOrphanKeysResult>;
|
|
814
|
+
/**
|
|
815
|
+
* Scan Vue/TS source files to find where translation keys are referenced.
|
|
816
|
+
*/
|
|
817
|
+
declare function scanCodeUsage(opts: {
|
|
818
|
+
keys?: string[];
|
|
819
|
+
scanDirs?: string[];
|
|
820
|
+
excludeDirs?: string[];
|
|
821
|
+
projectDir?: string;
|
|
822
|
+
outputFile?: string;
|
|
823
|
+
}): Promise<CodeUsageResult>;
|
|
824
|
+
/**
|
|
825
|
+
* Find translation keys not referenced in source code and remove them.
|
|
826
|
+
*/
|
|
827
|
+
declare function removeOrphanKeys(opts: {
|
|
828
|
+
layer?: string;
|
|
829
|
+
locale?: string;
|
|
830
|
+
/** Explicit scan roots — manual scope control, same semantics as {@link findOrphanKeys}. */
|
|
831
|
+
scanDirs?: string[];
|
|
832
|
+
excludeDirs?: string[];
|
|
833
|
+
dryRun?: boolean;
|
|
834
|
+
projectDir?: string;
|
|
835
|
+
outputFile?: string;
|
|
836
|
+
/** Also write the orphan findings as a GitLab Code Quality JSON array to this path. */
|
|
837
|
+
codequalityOutput?: string;
|
|
838
|
+
}): Promise<RemoveOrphanKeysResult>;
|
|
839
|
+
//# sourceMappingURL=ops-orphans.d.ts.map
|
|
840
|
+
//#endregion
|
|
841
|
+
//#region src/core/ops-duplicates.d.ts
|
|
842
|
+
/**
|
|
843
|
+
* Cross-layer duplicate-key detection: keys defined in both a shared layer
|
|
844
|
+
* and a consuming child layer, compared in one reference locale.
|
|
845
|
+
*/
|
|
846
|
+
interface DuplicateKeyCollision {
|
|
847
|
+
key: string;
|
|
848
|
+
sharedLayer: string;
|
|
849
|
+
childLayer: string;
|
|
850
|
+
sharedValue: unknown;
|
|
851
|
+
childValue: unknown;
|
|
852
|
+
divergent: boolean;
|
|
853
|
+
}
|
|
854
|
+
interface FindDuplicateKeysSummary {
|
|
855
|
+
totalCollisions: number;
|
|
856
|
+
divergentCount: number;
|
|
857
|
+
pairsChecked: number;
|
|
858
|
+
locale: string;
|
|
859
|
+
message?: string;
|
|
860
|
+
}
|
|
861
|
+
interface FindDuplicateKeysResult {
|
|
862
|
+
collisions: DuplicateKeyCollision[];
|
|
863
|
+
guidance: string;
|
|
864
|
+
summary: FindDuplicateKeysSummary;
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Find keys defined in both a shared layer and a consuming child layer,
|
|
868
|
+
* comparing values in a single reference locale (default: the project
|
|
869
|
+
* default locale). Pure locale-file I/O — no source scanning.
|
|
870
|
+
*/
|
|
871
|
+
declare function findDuplicateKeys(opts?: {
|
|
872
|
+
locale?: string;
|
|
873
|
+
projectDir?: string;
|
|
874
|
+
outputFile?: string;
|
|
875
|
+
}): Promise<FindDuplicateKeysResult | {
|
|
876
|
+
reportFile: string;
|
|
877
|
+
summary: FindDuplicateKeysSummary;
|
|
878
|
+
}>;
|
|
879
|
+
//# sourceMappingURL=ops-duplicates.d.ts.map
|
|
880
|
+
//#endregion
|
|
881
|
+
//#region src/core/ops-check.d.ts
|
|
882
|
+
/**
|
|
883
|
+
* Used-but-undefined key detection — the inverse of orphan scanning.
|
|
884
|
+
*
|
|
885
|
+
* A key referenced in source code but defined in no locale file of the
|
|
886
|
+
* using app's consumed layers renders as a raw key at runtime. Nothing
|
|
887
|
+
* else catches this direction (orphan scanning only computes
|
|
888
|
+
* locale − code; this computes code − locale, per scan unit).
|
|
889
|
+
*/
|
|
890
|
+
interface KeyUsageLocation {
|
|
891
|
+
/** Source file path, relative to the project dir. */
|
|
892
|
+
file: string;
|
|
893
|
+
line: number;
|
|
894
|
+
}
|
|
895
|
+
interface UndefinedKeyFinding {
|
|
896
|
+
key: string;
|
|
897
|
+
/** Scan unit the usage lives in (app name, layer name, or project-root). */
|
|
898
|
+
app: string;
|
|
899
|
+
/** Layers whose keys this unit can resolve — all were searched. */
|
|
900
|
+
searchedLayers: string[];
|
|
901
|
+
usages: KeyUsageLocation[];
|
|
902
|
+
}
|
|
903
|
+
interface UncertainKeyFinding extends UndefinedKeyFinding {
|
|
904
|
+
/** Why this is not a hard finding. */
|
|
905
|
+
reason: string;
|
|
906
|
+
}
|
|
907
|
+
interface CheckUndefinedKeysSummary {
|
|
908
|
+
/** Distinct statically referenced keys across all scan units. */
|
|
909
|
+
usedKeysChecked: number;
|
|
910
|
+
undefinedCount: number;
|
|
911
|
+
uncertainCount: number;
|
|
912
|
+
/** Unresolvable keys excluded by orphanScan ignorePatterns. */
|
|
913
|
+
ignoredCount: number;
|
|
914
|
+
filesScanned: number;
|
|
915
|
+
locale: string;
|
|
916
|
+
/** Scan unit → layers searched for that unit's key usages. */
|
|
917
|
+
searchedLayersByApp: Record<string, string[]>;
|
|
918
|
+
message: string;
|
|
919
|
+
}
|
|
920
|
+
interface CheckUndefinedKeysResult {
|
|
921
|
+
undefinedKeys: UndefinedKeyFinding[];
|
|
922
|
+
uncertainKeys: UncertainKeyFinding[];
|
|
923
|
+
limitation: string;
|
|
924
|
+
summary: CheckUndefinedKeysSummary;
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Find keys referenced in source code that resolve to no definition in the
|
|
928
|
+
* using app's consumed layers (reference locale, default: project default).
|
|
929
|
+
*
|
|
930
|
+
* Mirrors the orphan scan's per-unit structure: with no explicit scanDirs,
|
|
931
|
+
* the scope-aware plan from the layer graph decides which layers each scan
|
|
932
|
+
* unit's code can resolve (the inversion of the orphan scan's
|
|
933
|
+
* scopeByLayer — a unit resolves exactly the layers it vouches for). The
|
|
934
|
+
* graph's degenerate semantics carry over: with no app info every layer is
|
|
935
|
+
* resolvable everywhere, so only keys defined in NO layer are flagged.
|
|
936
|
+
*/
|
|
937
|
+
declare function checkUndefinedKeys(opts?: {
|
|
938
|
+
locale?: string;
|
|
939
|
+
/**
|
|
940
|
+
* Explicit scan roots — manual scope control. Every layer is treated as
|
|
941
|
+
* resolvable from every scanned dir (global behavior, no per-app scoping).
|
|
942
|
+
*/
|
|
943
|
+
scanDirs?: string[];
|
|
944
|
+
excludeDirs?: string[];
|
|
945
|
+
projectDir?: string;
|
|
946
|
+
outputFile?: string;
|
|
947
|
+
/** Also write the findings as a GitLab Code Quality JSON array to this path. */
|
|
948
|
+
codequalityOutput?: string;
|
|
949
|
+
}): Promise<CheckUndefinedKeysResult | {
|
|
950
|
+
reportFile: string;
|
|
951
|
+
summary: CheckUndefinedKeysSummary;
|
|
952
|
+
}>;
|
|
953
|
+
//# sourceMappingURL=ops-check.d.ts.map
|
|
954
|
+
//#endregion
|
|
955
|
+
//#region src/config/detector.d.ts
|
|
956
|
+
declare function detectI18nConfig(projectDir: string): Promise<I18nConfig>;
|
|
957
|
+
declare function clearConfigCache(): void;
|
|
958
|
+
declare function getCachedConfig(): I18nConfig | null;
|
|
959
|
+
//# sourceMappingURL=detector.d.ts.map
|
|
960
|
+
|
|
961
|
+
//#endregion
|
|
962
|
+
//#region src/config/layer-graph.d.ts
|
|
963
|
+
/**
|
|
964
|
+
* Queryable view over the layer topology a resolved {@link I18nConfig}
|
|
965
|
+
* already carries: which locale dirs are canonical (alias-free), which
|
|
966
|
+
* layer owns an aliased dir, and which apps consume which layers.
|
|
967
|
+
*
|
|
968
|
+
* This is a pure derivation — no filesystem access, no config-shape
|
|
969
|
+
* changes. Cross-layer tooling (duplicate detection, scope-aware orphan
|
|
970
|
+
* scanning) builds on these queries instead of name-matching heuristics.
|
|
971
|
+
*
|
|
972
|
+
* ## Degenerate-case semantics
|
|
973
|
+
*
|
|
974
|
+
* These are load-bearing for consumers (scope-aware scanning must never
|
|
975
|
+
* wrongly narrow its scan scope):
|
|
976
|
+
*
|
|
977
|
+
* - **No app info** (`config.apps` empty or absent, e.g. hand-built
|
|
978
|
+
* configs): consumption edges are unknowable. `appsUsingLayer` and
|
|
979
|
+
* `layersOfApp` return `[]`, and `sharedLayers` conservatively contains
|
|
980
|
+
* *every* canonical layer — with no ownership information, every
|
|
981
|
+
* layer's keys must be treated as globally visible.
|
|
982
|
+
* - **Single-app config** (generic/Laravel/Vue/React adapters, or a Nuxt
|
|
983
|
+
* project with one app): the strict definition applies, so
|
|
984
|
+
* `sharedLayers` is empty (no layer is consumed by more than one app)
|
|
985
|
+
* and `appsUsingLayer` returns that one app for the layers it consumes.
|
|
986
|
+
* Per-layer scope then equals the whole project, which is correct.
|
|
987
|
+
* - **Canonical layer consumed by no app** (in a multi-app config):
|
|
988
|
+
* `appsUsingLayer` returns `[]` and the layer is not in `sharedLayers`.
|
|
989
|
+
* Callers should treat such layers conservatively (global scope).
|
|
990
|
+
*/
|
|
991
|
+
interface LayerGraph {
|
|
992
|
+
/**
|
|
993
|
+
* Alias-free locale dirs, in `config.localeDirs` order. Aliased entries
|
|
994
|
+
* (e.g. `app-outlook` pointing at `app-shop`'s dir) are excluded.
|
|
995
|
+
*/
|
|
996
|
+
canonicalLayers: LocaleDir[];
|
|
997
|
+
/**
|
|
998
|
+
* Resolve a layer name to the canonical layer that owns its locale dir.
|
|
999
|
+
* Follows chained `aliasOf` links (an alias may point at a layer that
|
|
1000
|
+
* was itself demoted to an alias). Identity for canonical names and for
|
|
1001
|
+
* names unknown to `localeDirs` (e.g. layers without locale dirs).
|
|
1002
|
+
*/
|
|
1003
|
+
ownerOf: (layer: string) => string;
|
|
1004
|
+
/**
|
|
1005
|
+
* Names of apps whose consumed layers include the given layer. The
|
|
1006
|
+
* queried name and each app's layer list are alias-resolved via
|
|
1007
|
+
* {@link ownerOf} first, so querying an alias name yields the owner's
|
|
1008
|
+
* consumers. Returns `[]` when no app info exists.
|
|
1009
|
+
*/
|
|
1010
|
+
appsUsingLayer: (layer: string) => string[];
|
|
1011
|
+
/**
|
|
1012
|
+
* Canonical layers consumed by more than one app — e.g. a shared root
|
|
1013
|
+
* layer in a multi-app monorepo, identified purely from consumption
|
|
1014
|
+
* edges (no name matching). When no app info exists, contains every
|
|
1015
|
+
* canonical layer (see degenerate-case semantics above).
|
|
1016
|
+
*/
|
|
1017
|
+
sharedLayers: LocaleDir[];
|
|
1018
|
+
/**
|
|
1019
|
+
* Canonical layers the given app consumes (alias entries in the app's
|
|
1020
|
+
* layer list resolve to their owners; layers without locale dirs are
|
|
1021
|
+
* omitted). Returns `[]` for unknown apps or when no app info exists.
|
|
1022
|
+
*/
|
|
1023
|
+
layersOfApp: (app: string) => LocaleDir[];
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Build a {@link LayerGraph} from a resolved config's `localeDirs`
|
|
1027
|
+
* (with their `aliasOf` markers) and `apps` (app → consumed-layers edges).
|
|
1028
|
+
*/
|
|
1029
|
+
declare function buildLayerGraph(config: I18nConfig): LayerGraph;
|
|
1030
|
+
//# sourceMappingURL=layer-graph.d.ts.map
|
|
1031
|
+
//#endregion
|
|
1032
|
+
//#region src/io/locale-data.d.ts
|
|
1033
|
+
declare function readLocaleData(config: I18nConfig, layer: string, locale: LocaleDefinition): Promise<Record<string, unknown>>;
|
|
1034
|
+
/**
|
|
1035
|
+
* Read, mutate, and write back locale data for a locale in a layer.
|
|
1036
|
+
*
|
|
1037
|
+
* The mutation function receives the merged locale object (same shape as readLocaleData)
|
|
1038
|
+
* and may modify it in-place. After mutation:
|
|
1039
|
+
*
|
|
1040
|
+
* - Nuxt: Writes the entire object back to the single JSON file
|
|
1041
|
+
* - Laravel / Next.js / React: Splits by top-level namespace keys and writes each to its file.
|
|
1042
|
+
* New namespaces create new files. Empty namespaces delete the content (write empty object).
|
|
1043
|
+
*
|
|
1044
|
+
* Returns the set of file paths that were written.
|
|
1045
|
+
*/
|
|
1046
|
+
//#endregion
|
|
1047
|
+
//#region src/utils/errors.d.ts
|
|
1048
|
+
/** Extract a human-readable message from any thrown value. */
|
|
1049
|
+
declare function toErrorMessage(error: unknown): string;
|
|
1050
|
+
declare class ToolError extends Error {
|
|
1051
|
+
readonly code: string;
|
|
1052
|
+
constructor(message: string, code: string);
|
|
1053
|
+
}
|
|
1054
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
1055
|
+
//#endregion
|
|
1056
|
+
//#region src/llm/providers.d.ts
|
|
1057
|
+
type LlmProvider = 'openai' | 'anthropic' | 'google';
|
|
1058
|
+
/** How a provider failure should be handled by the caller. */
|
|
1059
|
+
type TranslateProviderErrorKind = 'auth' | 'rate-limit' | 'provider' | 'config';
|
|
1060
|
+
/**
|
|
1061
|
+
* A classified provider failure. `auth` errors are not retryable (the caller
|
|
1062
|
+
* should abort the run), `rate-limit` errors should be retried with backoff,
|
|
1063
|
+
* and `provider` covers everything else (server errors, network, …).
|
|
1064
|
+
* `config` marks an unusable provider setup and is raised while building the
|
|
1065
|
+
* TranslateFn, before any request exists — so it surfaces from the command
|
|
1066
|
+
* and never reaches the retry loop.
|
|
1067
|
+
*/
|
|
1068
|
+
declare class TranslateProviderError extends Error {
|
|
1069
|
+
readonly kind: TranslateProviderErrorKind;
|
|
1070
|
+
readonly status?: number;
|
|
1071
|
+
constructor(message: string, kind: TranslateProviderErrorKind, status?: number);
|
|
1072
|
+
}
|
|
1073
|
+
/**
|
|
1074
|
+
* Classify an SDK error into a TranslateProviderError:
|
|
1075
|
+
* 401/403 → auth, 429 → rate-limit, anything else → provider.
|
|
1076
|
+
* Already-classified errors pass through unchanged.
|
|
1077
|
+
*/
|
|
1078
|
+
declare function classifyProviderError(error: unknown): TranslateProviderError;
|
|
1079
|
+
interface LlmProviderConfig {
|
|
1080
|
+
provider: LlmProvider;
|
|
1081
|
+
model: string;
|
|
1082
|
+
/** Override API key. Falls back to env vars */
|
|
1083
|
+
apiKey?: string;
|
|
1084
|
+
/** Base URL override for proxies / compatible APIs */
|
|
1085
|
+
baseUrl?: string;
|
|
1086
|
+
}
|
|
1087
|
+
/** Environment variable carrying the provider base URL override. */
|
|
1088
|
+
declare const BASE_URL_ENV = "I18N_BASE_URL";
|
|
1089
|
+
/**
|
|
1090
|
+
* Resolve the provider base URL from its three sources, highest precedence
|
|
1091
|
+
* first: an explicit flag, the I18N_BASE_URL env var, then the project
|
|
1092
|
+
* config's `providerBaseUrl`.
|
|
1093
|
+
*
|
|
1094
|
+
* Blank values count as unset. Shells produce them routinely — `--baseUrl
|
|
1095
|
+
* "$UNSET"` or an exported-but-empty variable — and a blank must not shadow a
|
|
1096
|
+
* real endpoint configured further down the chain. A blank in the config file
|
|
1097
|
+
* is a different case: it cannot arise by accident, so the strict schema
|
|
1098
|
+
* rejects it at load time rather than letting it reach this function.
|
|
1099
|
+
*/
|
|
1100
|
+
declare function resolveProviderBaseUrl(sources: {
|
|
1101
|
+
flag?: string;
|
|
1102
|
+
env?: string;
|
|
1103
|
+
config?: string;
|
|
1104
|
+
}): string | undefined;
|
|
1105
|
+
/**
|
|
1106
|
+
* Create a TranslateFn from an LLM provider config.
|
|
1107
|
+
* Throws if the provider SDK is not installed or API key is missing.
|
|
1108
|
+
*/
|
|
1109
|
+
declare function createTranslateFn(config: LlmProviderConfig): Promise<TranslateFn>;
|
|
1110
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
1111
|
+
//#endregion
|
|
1112
|
+
//#region src/config/project-config.d.ts
|
|
1113
|
+
/**
|
|
1114
|
+
* Load the project's declared configuration, from either place it can be
|
|
1115
|
+
* declared: `i18n-kit.config.ts` and `.i18n-mcp.json`. Both are searched from
|
|
1116
|
+
* projectDir upwards, the way ESLint, Prettier and tsconfig resolve configs.
|
|
1117
|
+
*
|
|
1118
|
+
* Returns null when neither exists — the case that must keep behaving exactly
|
|
1119
|
+
* as it did before there were two. Throws ConfigError when either file is
|
|
1120
|
+
* present but unusable, or when the two disagree.
|
|
1121
|
+
*
|
|
1122
|
+
* Every adapter funnels through here, which is what makes the typed config
|
|
1123
|
+
* work for all of them rather than for whichever one was taught about it.
|
|
1124
|
+
*/
|
|
1125
|
+
declare function loadProjectConfig(projectDir: string): Promise<ProjectConfig | null>;
|
|
1126
|
+
//# sourceMappingURL=project-config.d.ts.map
|
|
1127
|
+
|
|
1128
|
+
//#endregion
|
|
1129
|
+
export { AddTranslationsResult, BASE_URL_ENV, type CheckUndefinedKeysResult, type CheckUndefinedKeysSummary, CodeUsageRef, CodeUsageResult, type DuplicateKeyCollision, DynamicKeyRef, EmptyTranslationsResult, type FindDuplicateKeysResult, type FindDuplicateKeysSummary, FindOrphanKeysResult, GeneratedProjectConfig, type I18nConfig, type I18nKitConfig, InitProjectConfigResult, type KeyUsageLocation, type LayerGraph, LayerStatus, type LlmProvider, type LlmProviderConfig, type LocaleDefinition, type LocaleDir, LocaleDirInfo, type LocaleRefAmbiguity, LocaleRefInfo, LocaleStatus, MisplacedUsageRef, MissingTranslationsResult, MutationPreview, MutationResult, PlaceholderValidationIssue, PlaceholderValidationResult, ProgressFn, type ProjectConfig, RemoveOrphanKeysResult, RemoveTranslationsPreview, RemoveTranslationsResult, RenameTranslationKeyPreview, RenameTranslationKeyResult, ScaffoldLocaleFileInfo, ScaffoldLocaleResult, ScanCodeUsageResult, SearchMatch, SearchTranslationsResult, ToolError, TranslateAllLayersResult, TranslateAllLayersSummary, TranslateFailReason, TranslateFn, TranslateKeyLocaleIssue, TranslateKeyResult, TranslateLayerTotals, TranslateMissingCompactEntry, TranslateMissingLocaleResult, TranslateMissingOutcome, TranslateMissingResult, TranslateMode, TranslateProviderError, type TranslateProviderErrorKind, TranslateRequest, TranslateResponse, TranslateSkipReason, TranslationStatusResult, TranslationStatusSummary, type UncertainKeyFinding, type UndefinedKeyFinding, UnresolvedKeyWarningRef, UnresolvedLocaleRef, UpdateTranslationsResult, WriteTranslationsResult, addTranslations, buildLayerGraph, checkUndefinedKeys, classifyProviderError, clearConfigCache, createTranslateFn, defineI18nKitConfig, detectConfig, detectI18nConfig, findDuplicateKeys, findEmptyTranslations, findLocaleImpl, findOrphanKeys, getCachedConfig, getMissingTranslations, getTranslationStatus, getTranslations, listLocaleDirs, listNamespaces, loadProjectConfig, readLocaleData, removeOrphanKeys, removeTranslations, renameTranslationKey, resolveProtectedLocales, resolveProviderBaseUrl, scaffoldLocaleFiles, scanCodeUsage, searchTranslations, toErrorMessage, translateKey, translateMissing, updateTranslations, writeTranslations };
|
|
1130
|
+
//# sourceMappingURL=index-BtSA6-iT.d.ts.map
|