@the-i18n-kit/cli 5.0.0 → 7.0.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 +21 -0
- package/README.md +8 -58
- package/dist/bin.js +1 -6
- package/dist/bin.js.map +1 -1
- package/dist/{_shared-DFyy3sh8.js → cli-waEjbUM1.js} +157 -27
- package/dist/cli-waEjbUM1.js.map +1 -0
- package/dist/config/framework/stubs/{next-intl-routing-Cwaa3f4R.d.ts → next-intl-routing-i6Mlxwdt.d.ts} +1 -1
- package/dist/config/framework/stubs/{next-intl-routing-Cwaa3f4R.d.ts.map → next-intl-routing-i6Mlxwdt.d.ts.map} +1 -1
- package/dist/{define-config-BaZ1dZph.d.ts → define-config-ChY3jk6K.d.ts} +26 -4
- package/dist/define-config-ChY3jk6K.d.ts.map +1 -0
- package/dist/{define-config-CLgKN-7N.d.ts → define-config-e0B0VHq7.d.ts} +1 -1
- package/dist/define-config.d.ts +1 -1
- package/dist/descriptors-10sgyqEs.js +1225 -0
- package/dist/descriptors-10sgyqEs.js.map +1 -0
- package/dist/detector-BJTkyhQ0.js +5 -0
- package/dist/detector-DtFY4qm3.js +2189 -0
- package/dist/detector-DtFY4qm3.js.map +1 -0
- package/dist/{index-DCG3dOdC.d.ts → index-CdjJ71Ag.d.ts} +665 -250
- package/dist/index-CdjJ71Ag.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -5
- package/dist/json-writer-D0b6vEax.js +2 -0
- package/dist/json-writer-ek8yEI5R.js +342 -0
- package/dist/json-writer-ek8yEI5R.js.map +1 -0
- package/dist/{operations-CTo44gPu.js → operations-CNqEBD__.js} +1505 -3285
- package/dist/operations-CNqEBD__.js.map +1 -0
- package/dist/operations-D7IMu_xY.js +8 -0
- package/dist/php-reader-BGx6Ii2d.js +2 -0
- package/dist/{php-reader-3Fgw80zK.js → php-reader-DRpcRVzv.js} +6 -3
- package/dist/{php-reader-3Fgw80zK.js.map → php-reader-DRpcRVzv.js.map} +1 -1
- package/dist/{providers-CHE2ffi6.js → project-config-C3ao4Uii.js} +24 -214
- package/dist/project-config-C3ao4Uii.js.map +1 -0
- package/dist/providers-BbVPelvp.js +406 -0
- package/dist/providers-BbVPelvp.js.map +1 -0
- package/dist/report-By1-5JtO.js +37 -0
- package/dist/report-By1-5JtO.js.map +1 -0
- package/dist/report-CHZgH9Wy.js +2 -0
- package/package.json +11 -23
- package/dist/_shared-DFyy3sh8.js.map +0 -1
- package/dist/add-C-qs8iBa.js +0 -40
- package/dist/add-C-qs8iBa.js.map +0 -1
- package/dist/check-BI1orjXb.js +0 -41
- package/dist/check-BI1orjXb.js.map +0 -1
- package/dist/cli-DsFuVJNP.js +0 -74
- package/dist/cli-DsFuVJNP.js.map +0 -1
- package/dist/config/framework/stubs/unplugin-vue-i18n-1ud7-Ly8.d.ts +0 -25
- package/dist/config/framework/stubs/unplugin-vue-i18n-1ud7-Ly8.d.ts.map +0 -1
- package/dist/config/framework/stubs/unplugin-vue-i18n.js +0 -26
- package/dist/config/framework/stubs/unplugin-vue-i18n.js.map +0 -1
- package/dist/define-config-BaZ1dZph.d.ts.map +0 -1
- package/dist/detect-7cVfsNJP.js +0 -17
- package/dist/detect-7cVfsNJP.js.map +0 -1
- package/dist/empty-DB8Hl_8u.js +0 -36
- package/dist/empty-DB8Hl_8u.js.map +0 -1
- package/dist/find-duplicates-CmEqBfby.js +0 -42
- package/dist/find-duplicates-CmEqBfby.js.map +0 -1
- package/dist/get-BE21Iy6N.js +0 -41
- package/dist/get-BE21Iy6N.js.map +0 -1
- package/dist/index-DCG3dOdC.d.ts.map +0 -1
- package/dist/init-BtzmhsOM.js +0 -33
- package/dist/init-BtzmhsOM.js.map +0 -1
- package/dist/list-dirs-DUQbwvlE.js +0 -17
- package/dist/list-dirs-DUQbwvlE.js.map +0 -1
- package/dist/missing-CcYrgd54.js +0 -51
- package/dist/missing-CcYrgd54.js.map +0 -1
- package/dist/move-B2px6Ck-.js +0 -50
- package/dist/move-B2px6Ck-.js.map +0 -1
- package/dist/operations-CTo44gPu.js.map +0 -1
- package/dist/php-reader-CpnaPSpZ.js +0 -2
- package/dist/providers-CHE2ffi6.js.map +0 -1
- package/dist/remove-DTbqM4bR.js +0 -41
- package/dist/remove-DTbqM4bR.js.map +0 -1
- package/dist/remove-orphans-Dfzu7hRz.js +0 -57
- package/dist/remove-orphans-Dfzu7hRz.js.map +0 -1
- package/dist/rename-C_rFKkU4.js +0 -45
- package/dist/rename-C_rFKkU4.js.map +0 -1
- package/dist/rename-notice-BV8HNX3O.js +0 -25
- package/dist/rename-notice-BV8HNX3O.js.map +0 -1
- package/dist/rename-notice-Cx1vuTRz.js +0 -2
- package/dist/scaffold-CUimlNqR.js +0 -39
- package/dist/scaffold-CUimlNqR.js.map +0 -1
- package/dist/scan-BkOIYhjZ.js +0 -31
- package/dist/scan-BkOIYhjZ.js.map +0 -1
- package/dist/search-0io1BcsY.js +0 -49
- package/dist/search-0io1BcsY.js.map +0 -1
- package/dist/status-Bp-SzjTN.js +0 -45
- package/dist/status-Bp-SzjTN.js.map +0 -1
- package/dist/translate-cCb2Z57w.js +0 -92
- package/dist/translate-cCb2Z57w.js.map +0 -1
- package/dist/translate-key-DHLWEmrA.js +0 -73
- package/dist/translate-key-DHLWEmrA.js.map +0 -1
- package/dist/update-DV4ijRVB.js +0 -40
- package/dist/update-DV4ijRVB.js.map +0 -1
- package/dist/write-Czzm_Nb0.js +0 -47
- package/dist/write-Czzm_Nb0.js.map +0 -1
- /package/dist/{bin-DrKRgnr9.d.ts → bin-NyzIHE2F.d.ts} +0 -0
|
@@ -1,7 +1,127 @@
|
|
|
1
|
-
import { a as LocaleDir, i as LocaleDefinition, n as defineI18nKitConfig, o as ProjectConfig, r as I18nConfig, s as LocaleFileFormat, t as I18nKitConfig } from "./define-config-
|
|
1
|
+
import { a as LocaleDir, i as LocaleDefinition, n as defineI18nKitConfig, o as ProjectConfig, r as I18nConfig, s as LocaleFileFormat, t as I18nKitConfig } from "./define-config-ChY3jk6K.js";
|
|
2
2
|
|
|
3
|
-
//#region src/
|
|
3
|
+
//#region src/config/layer-graph.d.ts
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Queryable view over the layer topology a resolved {@link I18nConfig}
|
|
7
|
+
* already carries: which locale dirs are canonical (alias-free), which
|
|
8
|
+
* layer owns an aliased dir, and which apps consume which layers.
|
|
9
|
+
*
|
|
10
|
+
* This is a pure derivation — no filesystem access, no config-shape
|
|
11
|
+
* changes. Cross-layer tooling (duplicate detection, scope-aware orphan
|
|
12
|
+
* scanning) builds on these queries instead of name-matching heuristics.
|
|
13
|
+
*
|
|
14
|
+
* ## Degenerate-case semantics
|
|
15
|
+
*
|
|
16
|
+
* These are load-bearing for consumers (scope-aware scanning must never
|
|
17
|
+
* wrongly narrow its scan scope):
|
|
18
|
+
*
|
|
19
|
+
* - **No app info** (`config.apps` empty or absent, e.g. hand-built
|
|
20
|
+
* configs): consumption edges are unknowable. `appsUsingLayer` and
|
|
21
|
+
* `layersOfApp` return `[]`, and `sharedLayers` conservatively contains
|
|
22
|
+
* *every* canonical layer — with no ownership information, every
|
|
23
|
+
* layer's keys must be treated as globally visible.
|
|
24
|
+
* - **Single-app config** (generic/Laravel/React adapters, or a Nuxt
|
|
25
|
+
* project with one app): the strict definition applies, so
|
|
26
|
+
* `sharedLayers` is empty (no layer is consumed by more than one app)
|
|
27
|
+
* and `appsUsingLayer` returns that one app for the layers it consumes.
|
|
28
|
+
* Per-layer scope then equals the whole project, which is correct.
|
|
29
|
+
* - **Canonical layer consumed by no app** (in a multi-app config):
|
|
30
|
+
* `appsUsingLayer` returns `[]` and the layer is not in `sharedLayers`.
|
|
31
|
+
* Callers should treat such layers conservatively (global scope).
|
|
32
|
+
*/
|
|
33
|
+
interface LayerGraph {
|
|
34
|
+
/**
|
|
35
|
+
* Alias-free locale dirs, in `config.localeDirs` order. Aliased entries
|
|
36
|
+
* (e.g. `app-outlook` pointing at `app-shop`'s dir) are excluded.
|
|
37
|
+
*/
|
|
38
|
+
canonicalLayers: LocaleDir[];
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a layer name to the canonical layer that owns its locale dir.
|
|
41
|
+
* Follows chained `aliasOf` links (an alias may point at a layer that
|
|
42
|
+
* was itself demoted to an alias). Identity for canonical names and for
|
|
43
|
+
* names unknown to `localeDirs` (e.g. layers without locale dirs).
|
|
44
|
+
*/
|
|
45
|
+
ownerOf: (layer: string) => string;
|
|
46
|
+
/**
|
|
47
|
+
* Names of apps whose consumed layers include the given layer. The
|
|
48
|
+
* queried name and each app's layer list are alias-resolved via
|
|
49
|
+
* {@link ownerOf} first, so querying an alias name yields the owner's
|
|
50
|
+
* consumers. Returns `[]` when no app info exists.
|
|
51
|
+
*/
|
|
52
|
+
appsUsingLayer: (layer: string) => string[];
|
|
53
|
+
/**
|
|
54
|
+
* Canonical layers consumed by more than one app — e.g. a shared root
|
|
55
|
+
* layer in a multi-app monorepo, identified purely from consumption
|
|
56
|
+
* edges (no name matching). When no app info exists, contains every
|
|
57
|
+
* canonical layer (see degenerate-case semantics above).
|
|
58
|
+
*/
|
|
59
|
+
sharedLayers: LocaleDir[];
|
|
60
|
+
/**
|
|
61
|
+
* Canonical layers the given app consumes (alias entries in the app's
|
|
62
|
+
* layer list resolve to their owners; layers without locale dirs are
|
|
63
|
+
* omitted). Returns `[]` for unknown apps or when no app info exists.
|
|
64
|
+
*/
|
|
65
|
+
layersOfApp: (app: string) => LocaleDir[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Build a {@link LayerGraph} from a resolved config's `localeDirs`
|
|
69
|
+
* (with their `aliasOf` markers) and `apps` (app → consumed-layers edges).
|
|
70
|
+
*/
|
|
71
|
+
declare function buildLayerGraph(config: I18nConfig): LayerGraph;
|
|
72
|
+
/**
|
|
73
|
+
* The graph as plain data, for surfaces that can only carry JSON.
|
|
74
|
+
*
|
|
75
|
+
* {@link LayerGraph} is function-valued, so it cannot be serialised directly.
|
|
76
|
+
* This answers the question an agent actually has — *which layer does this key
|
|
77
|
+
* belong in* — which the flat layer list `discover` returned could not: a key
|
|
78
|
+
* used by more than one app belongs in a layer those apps share, and `shared`
|
|
79
|
+
* names those layers outright (#342).
|
|
80
|
+
*
|
|
81
|
+
* The degenerate cases documented on {@link LayerGraph} survive the flattening,
|
|
82
|
+
* because they are what keeps a consumer from wrongly narrowing scope:
|
|
83
|
+
* a config with no app info reports *every* canonical layer as shared, and a
|
|
84
|
+
* layer no app consumes appears in `consumers` with an empty array rather than
|
|
85
|
+
* being left out. Absent and "none" must not look alike here.
|
|
86
|
+
*/
|
|
87
|
+
interface SerializedLayerGraph {
|
|
88
|
+
/** Alias-free layer names, in `config.localeDirs` order. */
|
|
89
|
+
canonical: string[];
|
|
90
|
+
/** Canonical layers consumed by more than one app — where shared keys belong. */
|
|
91
|
+
shared: string[];
|
|
92
|
+
/** Alias layer name → the canonical layer whose locale dir it points at. */
|
|
93
|
+
aliases: Record<string, string>;
|
|
94
|
+
/** Canonical layer name → the apps consuming it. Every canonical layer is a key. */
|
|
95
|
+
consumers: Record<string, string[]>;
|
|
96
|
+
}
|
|
97
|
+
/** Flatten {@link buildLayerGraph}'s view of `config` into plain JSON. */
|
|
98
|
+
declare function serializeLayerGraph(config: I18nConfig): SerializedLayerGraph;
|
|
99
|
+
//# sourceMappingURL=layer-graph.d.ts.map
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/core/types.d.ts
|
|
102
|
+
/**
|
|
103
|
+
* The whole resolved project in one answer: the config, the locale dirs behind
|
|
104
|
+
* it, the topology those dirs form, and which locales are maintained by hand.
|
|
105
|
+
*
|
|
106
|
+
* A superset of `I18nConfig` rather than a wrapper around it, because every
|
|
107
|
+
* caller of the old three-call sequence merged the parts anyway and a nested
|
|
108
|
+
* `config` key would break each of them for nothing.
|
|
109
|
+
*/
|
|
110
|
+
interface DescribeProjectResult extends I18nConfig {
|
|
111
|
+
/**
|
|
112
|
+
* Canonical codes of the locales the translate operations leave alone. The
|
|
113
|
+
* raw refs stay visible under `projectConfig.protectedLocales`.
|
|
114
|
+
*/
|
|
115
|
+
protectedLocales: string[];
|
|
116
|
+
/** One entry per locale directory, with file counts and key namespaces. */
|
|
117
|
+
layers: LocaleDirInfo[];
|
|
118
|
+
/**
|
|
119
|
+
* Which layers are shared, which apps consume which layer, and what each
|
|
120
|
+
* alias points at — the topology behind the flat `layers` list, and what
|
|
121
|
+
* answers where a new key belongs.
|
|
122
|
+
*/
|
|
123
|
+
layerGraph: SerializedLayerGraph;
|
|
124
|
+
}
|
|
5
125
|
interface LocaleDirInfo {
|
|
6
126
|
layer: string;
|
|
7
127
|
path: string;
|
|
@@ -62,27 +182,6 @@ interface MutationResult {
|
|
|
62
182
|
/** Present only when a ref matched several locales and precedence picked one. */
|
|
63
183
|
ambiguousLocales?: LocaleRefAmbiguity[];
|
|
64
184
|
}
|
|
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
185
|
interface WriteTranslationsResult {
|
|
87
186
|
/** Present when dryRun=true */
|
|
88
187
|
dryRun?: boolean;
|
|
@@ -104,26 +203,6 @@ interface WriteTranslationsResult {
|
|
|
104
203
|
};
|
|
105
204
|
skippedKeys?: string[];
|
|
106
205
|
}
|
|
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
206
|
/**
|
|
128
207
|
* The config `init` emits. Only fields the matched adapter cannot derive:
|
|
129
208
|
* writing a copy of what the framework already states creates a second source
|
|
@@ -173,16 +252,13 @@ interface InitProjectConfigResult {
|
|
|
173
252
|
overwritten: boolean;
|
|
174
253
|
}
|
|
175
254
|
interface MissingTranslationsResult {
|
|
176
|
-
|
|
177
|
-
missing?: Record<string, Record<string, string[]>>;
|
|
255
|
+
missing: Record<string, Record<string, string[]>>;
|
|
178
256
|
summary: {
|
|
179
257
|
referenceLocale: string | LocaleRefInfo;
|
|
180
258
|
targetLocales: Array<string | LocaleRefInfo>;
|
|
181
259
|
layersScanned: string[];
|
|
182
260
|
totalMissingKeys: number;
|
|
183
261
|
};
|
|
184
|
-
/** Present when reportOutput is configured */
|
|
185
|
-
reportFile?: string;
|
|
186
262
|
}
|
|
187
263
|
interface LocaleStatus extends LocaleRefInfo {
|
|
188
264
|
total: number;
|
|
@@ -203,10 +279,21 @@ interface LayerStatus {
|
|
|
203
279
|
missing: number;
|
|
204
280
|
empty: number;
|
|
205
281
|
completion: number;
|
|
282
|
+
/**
|
|
283
|
+
* Apps whose declared layers include this one. Empty means either no app
|
|
284
|
+
* information exists (hand-built configs) or nothing consumes the layer.
|
|
285
|
+
*/
|
|
286
|
+
consumedBy: string[];
|
|
206
287
|
}
|
|
207
288
|
interface TranslationStatusSummary {
|
|
208
289
|
referenceLocale: LocaleRefInfo;
|
|
209
290
|
layersScanned: string[];
|
|
291
|
+
/**
|
|
292
|
+
* Scanned layers no app consumes — keys nothing can render. Stays empty
|
|
293
|
+
* unless the project declares more than one app, since a single-app project
|
|
294
|
+
* has no consumption edges worth reporting on.
|
|
295
|
+
*/
|
|
296
|
+
unconsumedLayers: string[];
|
|
210
297
|
localesChecked: number;
|
|
211
298
|
protectedLocales: string[];
|
|
212
299
|
totalKeys: number;
|
|
@@ -217,22 +304,31 @@ interface TranslationStatusSummary {
|
|
|
217
304
|
completionPercent: number;
|
|
218
305
|
}
|
|
219
306
|
interface TranslationStatusResult {
|
|
220
|
-
locales
|
|
221
|
-
layers
|
|
307
|
+
locales: LocaleStatus[];
|
|
308
|
+
layers: LayerStatus[];
|
|
309
|
+
/**
|
|
310
|
+
* Locale → layer → the keys `summary.emptyKeys` counts: empty in that target
|
|
311
|
+
* locale while the reference locale has a value. Present only when the caller
|
|
312
|
+
* asked to list them. Added to the result rather than replacing it, so asking
|
|
313
|
+
* which keys are empty still answers the coverage question that prompted it.
|
|
314
|
+
*/
|
|
315
|
+
empty?: Record<string, Record<string, string[]>>;
|
|
316
|
+
/**
|
|
317
|
+
* Layer → keys whose value is empty in the reference locale itself. Nothing
|
|
318
|
+
* to translate from, so excluded from every count; listed so a deliberate
|
|
319
|
+
* blank and a forgotten one can be told apart. Present only with `empty`,
|
|
320
|
+
* and only when there are any.
|
|
321
|
+
*/
|
|
322
|
+
emptyInReference?: Record<string, string[]>;
|
|
222
323
|
summary: TranslationStatusSummary;
|
|
223
|
-
/** Present when the full breakdown went to a file instead. */
|
|
224
|
-
reportFile?: string;
|
|
225
324
|
}
|
|
226
325
|
interface EmptyTranslationsResult {
|
|
227
|
-
|
|
228
|
-
emptyKeys?: Record<string, Record<string, string[]>>;
|
|
326
|
+
emptyKeys: Record<string, Record<string, string[]>>;
|
|
229
327
|
summary: {
|
|
230
328
|
totalEmpty: number;
|
|
231
329
|
localesChecked: string[];
|
|
232
330
|
layersChecked: string[];
|
|
233
331
|
};
|
|
234
|
-
/** Present when reportOutput is configured */
|
|
235
|
-
reportFile?: string;
|
|
236
332
|
}
|
|
237
333
|
interface SearchMatch {
|
|
238
334
|
layer: string;
|
|
@@ -297,6 +393,12 @@ interface MoveTranslationKeyPlanEntry {
|
|
|
297
393
|
*/
|
|
298
394
|
action: 'move' | 'deduplicate';
|
|
299
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* What a move returns: a rename result when the key stayed in its layer, a move
|
|
398
|
+
* result when it changed layers. A union rather than one merged shape, so
|
|
399
|
+
* neither half carries fields that can never be set for the other.
|
|
400
|
+
*/
|
|
401
|
+
type MoveTranslationKeyOutcome = MoveTranslationKeyResult | RenameTranslationKeyResult;
|
|
300
402
|
interface MoveTranslationKeyResult {
|
|
301
403
|
/** Present when dryRun=true */
|
|
302
404
|
dryRun?: boolean;
|
|
@@ -326,6 +428,29 @@ type TranslateMode = 'provider' | 'agent' | 'dry-run';
|
|
|
326
428
|
type TranslateFailReason = 'provider-error' | 'omitted-by-model' | 'placeholder-mismatch' | 'plural-mismatch' | 'write-error' | 'truncated';
|
|
327
429
|
/** Why a key or locale was intentionally not attempted. */
|
|
328
430
|
type TranslateSkipReason = 'no-provider' | 'already-translated' | 'protected-locale';
|
|
431
|
+
/** What translate_missing accepts. `layer` omitted means every layer at once. */
|
|
432
|
+
interface TranslateMissingOptions {
|
|
433
|
+
layer?: string;
|
|
434
|
+
referenceLocale?: string;
|
|
435
|
+
targetLocales?: string[];
|
|
436
|
+
locales?: string[];
|
|
437
|
+
keys?: string[];
|
|
438
|
+
batchSize?: number;
|
|
439
|
+
dryRun?: boolean;
|
|
440
|
+
compact?: boolean;
|
|
441
|
+
projectDir?: string;
|
|
442
|
+
/**
|
|
443
|
+
* Also re-translate keys whose target was written from source text that has
|
|
444
|
+
* changed since (translation memory only). Off by default: without it the
|
|
445
|
+
* operation still never touches an existing value, it only reports the stale
|
|
446
|
+
* ones in `stale`.
|
|
447
|
+
*/
|
|
448
|
+
overwriteStale?: boolean;
|
|
449
|
+
translateFn?: TranslateFn;
|
|
450
|
+
progressFn?: ProgressFn;
|
|
451
|
+
/** Called once after the pre-scan with the computed total number of progress steps. */
|
|
452
|
+
onProgressTotal?: (total: number) => void;
|
|
453
|
+
}
|
|
329
454
|
interface TranslateMissingLocaleResult {
|
|
330
455
|
mode: TranslateMode;
|
|
331
456
|
/** Number of missing keys found for this locale. Always equals
|
|
@@ -342,6 +467,14 @@ interface TranslateMissingLocaleResult {
|
|
|
342
467
|
key: string;
|
|
343
468
|
reason: TranslateSkipReason;
|
|
344
469
|
}>;
|
|
470
|
+
/**
|
|
471
|
+
* Translation-memory only: keys whose target value was written from source
|
|
472
|
+
* text that has changed since, and which this run left untouched. A bucket of
|
|
473
|
+
* its own, not part of `missing` — these keys are translated, just outdated —
|
|
474
|
+
* so the invariant above still holds. Re-translating them needs
|
|
475
|
+
* `overwriteStale`, which counts them into `missing` instead.
|
|
476
|
+
*/
|
|
477
|
+
stale?: string[];
|
|
345
478
|
batches?: number;
|
|
346
479
|
model?: string;
|
|
347
480
|
writeError?: string;
|
|
@@ -356,6 +489,7 @@ interface TranslateMissingCompactEntry {
|
|
|
356
489
|
failed: number;
|
|
357
490
|
skipped: number;
|
|
358
491
|
wouldTranslate?: number;
|
|
492
|
+
stale?: number;
|
|
359
493
|
batches?: number;
|
|
360
494
|
model?: string;
|
|
361
495
|
writeError?: string;
|
|
@@ -372,6 +506,8 @@ interface TranslateMissingResult {
|
|
|
372
506
|
totalFailed: number;
|
|
373
507
|
totalSkipped: number;
|
|
374
508
|
totalWouldTranslate?: number;
|
|
509
|
+
/** Translation-memory only: stale keys left untouched, across all locales. */
|
|
510
|
+
staleCount?: number;
|
|
375
511
|
layer: string;
|
|
376
512
|
referenceLocale: string | LocaleRefInfo;
|
|
377
513
|
targetLocales: Array<string | LocaleRefInfo>;
|
|
@@ -393,6 +529,8 @@ interface TranslateAllLayersSummary {
|
|
|
393
529
|
totalFailed: number;
|
|
394
530
|
totalSkipped: number;
|
|
395
531
|
totalWouldTranslate?: number;
|
|
532
|
+
/** Translation-memory only: stale keys left untouched, across all layers and locales. */
|
|
533
|
+
staleCount?: number;
|
|
396
534
|
/** Layer names that were translated. */
|
|
397
535
|
layers: string[];
|
|
398
536
|
byLayer: TranslateLayerTotals[];
|
|
@@ -425,6 +563,18 @@ interface TranslateKeyLocaleIssue {
|
|
|
425
563
|
reason: TranslateFailReason | 'read-error';
|
|
426
564
|
detail?: string;
|
|
427
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* One locale translate_key deliberately left alone. `reason` is a closed set;
|
|
568
|
+
* `stale` refines 'already-translated' rather than extending it, so a caller
|
|
569
|
+
* can tell an existing translation that still matches its source from one the
|
|
570
|
+
* source has since outgrown.
|
|
571
|
+
*/
|
|
572
|
+
interface TranslateKeySkip {
|
|
573
|
+
locale: string;
|
|
574
|
+
reason: TranslateSkipReason;
|
|
575
|
+
/** Translation-memory only: whether the existing value is out of date. */
|
|
576
|
+
stale?: boolean;
|
|
577
|
+
}
|
|
428
578
|
interface TranslateKeyResult {
|
|
429
579
|
key: string;
|
|
430
580
|
sourceLocale: LocaleRefInfo;
|
|
@@ -433,10 +583,7 @@ interface TranslateKeyResult {
|
|
|
433
583
|
translated: string[];
|
|
434
584
|
/** Dry-run only: locales that would be translated. */
|
|
435
585
|
wouldTranslate?: string[];
|
|
436
|
-
skipped:
|
|
437
|
-
locale: string;
|
|
438
|
-
reason: TranslateSkipReason;
|
|
439
|
-
}>;
|
|
586
|
+
skipped: TranslateKeySkip[];
|
|
440
587
|
failed: TranslateKeyLocaleIssue[];
|
|
441
588
|
filesWritten: number;
|
|
442
589
|
dryRun: boolean;
|
|
@@ -469,8 +616,7 @@ interface UnresolvedKeyWarningRef {
|
|
|
469
616
|
suggestedIgnorePattern?: string;
|
|
470
617
|
}
|
|
471
618
|
interface FindOrphanKeysResult {
|
|
472
|
-
|
|
473
|
-
orphanKeys?: Record<string, string[]>;
|
|
619
|
+
orphanKeys: Record<string, string[]>;
|
|
474
620
|
uncertainKeys?: Record<string, string[]>;
|
|
475
621
|
/**
|
|
476
622
|
* Keys kept alive solely by the bare-candidate net — nothing a frontend
|
|
@@ -504,13 +650,10 @@ interface FindOrphanKeysResult {
|
|
|
504
650
|
dynamicKeyWarning?: string;
|
|
505
651
|
dynamicKeys?: DynamicKeyRef[];
|
|
506
652
|
unresolvedKeyWarnings?: UnresolvedKeyWarningRef[];
|
|
507
|
-
/** Present when reportOutput is configured */
|
|
508
|
-
reportFile?: string;
|
|
509
653
|
}
|
|
510
654
|
/** Where each requested key is referenced in source. */
|
|
511
655
|
interface CodeUsageResult {
|
|
512
|
-
|
|
513
|
-
usages?: Record<string, CodeUsageRef[]>;
|
|
656
|
+
usages: Record<string, CodeUsageRef[]>;
|
|
514
657
|
/** Requested keys with no reference anywhere in the scanned source. */
|
|
515
658
|
notFoundInCode?: string[];
|
|
516
659
|
/** Dynamic expressions that could reach the requested keys. */
|
|
@@ -524,8 +667,6 @@ interface CodeUsageResult {
|
|
|
524
667
|
dirsScanned?: string[];
|
|
525
668
|
message?: string;
|
|
526
669
|
};
|
|
527
|
-
/** Present when the full report went to a file instead. */
|
|
528
|
-
reportFile?: string;
|
|
529
670
|
}
|
|
530
671
|
interface CodeUsageRef {
|
|
531
672
|
file: string;
|
|
@@ -544,8 +685,6 @@ interface ScanCodeUsageResult {
|
|
|
544
685
|
};
|
|
545
686
|
notFoundInCode?: string[];
|
|
546
687
|
dynamicKeys?: DynamicKeyRef[];
|
|
547
|
-
/** Present when reportOutput is configured */
|
|
548
|
-
reportFile?: string;
|
|
549
688
|
}
|
|
550
689
|
interface RemoveOrphanKeysResult {
|
|
551
690
|
orphanKeys?: Record<string, string[]>;
|
|
@@ -575,8 +714,6 @@ interface RemoveOrphanKeysResult {
|
|
|
575
714
|
dynamicKeyWarning?: string;
|
|
576
715
|
dynamicKeys?: DynamicKeyRef[];
|
|
577
716
|
unresolvedKeyWarnings?: UnresolvedKeyWarningRef[];
|
|
578
|
-
/** Present when reportOutput is configured */
|
|
579
|
-
reportFile?: string;
|
|
580
717
|
}
|
|
581
718
|
interface ScaffoldLocaleFileInfo {
|
|
582
719
|
locale: string;
|
|
@@ -625,7 +762,7 @@ declare function findLocaleImpl(config: I18nConfig, localeRef: string): LocaleDe
|
|
|
625
762
|
* project default. Throws LOCALE_NOT_FOUND listing the available codes.
|
|
626
763
|
*/
|
|
627
764
|
//#endregion
|
|
628
|
-
//#region src/core/
|
|
765
|
+
//#region src/core/translate/targets.d.ts
|
|
629
766
|
/**
|
|
630
767
|
* Resolve the config's `protectedLocales` entries (any locale ref: code,
|
|
631
768
|
* language tag, or file name) against the known locales. Entries that do not
|
|
@@ -633,6 +770,15 @@ declare function findLocaleImpl(config: I18nConfig, localeRef: string): LocaleDe
|
|
|
633
770
|
* definitions, deduplicated by canonical code.
|
|
634
771
|
*/
|
|
635
772
|
declare function resolveProtectedLocales(config: I18nConfig): LocaleDefinition[];
|
|
773
|
+
/**
|
|
774
|
+
* Resolve translate_missing target locales. Protected locales are excluded
|
|
775
|
+
* from the DEFAULT target set (returned separately so the caller can report
|
|
776
|
+
* them as skipped); naming one explicitly in targetLocales overrides the
|
|
777
|
+
* protection with a warning.
|
|
778
|
+
*/
|
|
779
|
+
|
|
780
|
+
//#endregion
|
|
781
|
+
//#region src/core/translate/run.d.ts
|
|
636
782
|
/**
|
|
637
783
|
* Find keys missing in target locales and translate them.
|
|
638
784
|
*
|
|
@@ -642,21 +788,7 @@ declare function resolveProtectedLocales(config: I18nConfig): LocaleDefinition[]
|
|
|
642
788
|
* When `layer` is omitted, every canonical locale-backed layer is translated
|
|
643
789
|
* in one run and the results are aggregated (see translateMissingAllLayers).
|
|
644
790
|
*/
|
|
645
|
-
declare function translateMissing(opts:
|
|
646
|
-
layer?: string;
|
|
647
|
-
referenceLocale?: string;
|
|
648
|
-
targetLocales?: string[];
|
|
649
|
-
locales?: string[];
|
|
650
|
-
keys?: string[];
|
|
651
|
-
batchSize?: number;
|
|
652
|
-
dryRun?: boolean;
|
|
653
|
-
compact?: boolean;
|
|
654
|
-
projectDir?: string;
|
|
655
|
-
translateFn?: TranslateFn;
|
|
656
|
-
progressFn?: ProgressFn;
|
|
657
|
-
/** Called once after the pre-scan with the computed total number of progress steps. */
|
|
658
|
-
onProgressTotal?: (total: number) => void;
|
|
659
|
-
}): Promise<TranslateMissingOutcome>;
|
|
791
|
+
declare function translateMissing(opts: TranslateMissingOptions): Promise<TranslateMissingOutcome>;
|
|
660
792
|
/**
|
|
661
793
|
* Translate one key from a source locale into target locales. Unlike
|
|
662
794
|
* translate_missing, this can overwrite stale existing target values.
|
|
@@ -673,9 +805,23 @@ declare function translateKey(opts: {
|
|
|
673
805
|
projectDir?: string;
|
|
674
806
|
translateFn?: TranslateFn;
|
|
675
807
|
}): Promise<TranslateKeyResult>;
|
|
676
|
-
//# sourceMappingURL=
|
|
808
|
+
//# sourceMappingURL=run.d.ts.map
|
|
677
809
|
//#endregion
|
|
678
810
|
//#region src/core/ops-read.d.ts
|
|
811
|
+
/**
|
|
812
|
+
* Everything a caller needs to know about a project before touching it:
|
|
813
|
+
* resolved config, locale directories, the layer topology, and which locales
|
|
814
|
+
* are hand-maintained.
|
|
815
|
+
*
|
|
816
|
+
* This composition used to live in the MCP `discover` handler, so the terminal
|
|
817
|
+
* had no way to ask the question its own docs told people to ask — and the two
|
|
818
|
+
* surfaces would have had to be kept in step by hand once one of them grew a
|
|
819
|
+
* field. Callers add whatever is theirs alone (the MCP server adds the
|
|
820
|
+
* translation backend it resolved at startup); the project half is here.
|
|
821
|
+
*/
|
|
822
|
+
declare function describeProject(opts?: {
|
|
823
|
+
projectDir?: string;
|
|
824
|
+
}): Promise<DescribeProjectResult>;
|
|
679
825
|
/**
|
|
680
826
|
* Detect the i18n configuration from the project, always bypassing the
|
|
681
827
|
* config cache (clears it first).
|
|
@@ -704,7 +850,6 @@ declare function getMissingTranslations(opts: {
|
|
|
704
850
|
targetLocales?: string[];
|
|
705
851
|
locales?: string[];
|
|
706
852
|
projectDir?: string;
|
|
707
|
-
outputFile?: string;
|
|
708
853
|
}): Promise<MissingTranslationsResult>;
|
|
709
854
|
/**
|
|
710
855
|
* Find translation keys that have empty string values in locale files.
|
|
@@ -713,8 +858,15 @@ declare function findEmptyTranslations(opts: {
|
|
|
713
858
|
layer?: string;
|
|
714
859
|
locale?: string;
|
|
715
860
|
projectDir?: string;
|
|
716
|
-
outputFile?: string;
|
|
717
861
|
}): Promise<EmptyTranslationsResult>;
|
|
862
|
+
/**
|
|
863
|
+
* The scan behind {@link findEmptyTranslations}, against a config the caller
|
|
864
|
+
* already has.
|
|
865
|
+
*
|
|
866
|
+
* Separate so `getTranslationStatus` can embed the listing under its own
|
|
867
|
+
* `--list-empty` flag without detecting the project a second time.
|
|
868
|
+
*/
|
|
869
|
+
|
|
718
870
|
/**
|
|
719
871
|
* Search translation files by key pattern or value substring.
|
|
720
872
|
*/
|
|
@@ -724,16 +876,7 @@ declare function searchTranslations(opts: {
|
|
|
724
876
|
layer?: string;
|
|
725
877
|
locale?: string;
|
|
726
878
|
projectDir?: string;
|
|
727
|
-
|
|
728
|
-
}): Promise<{
|
|
729
|
-
matches: SearchMatch[];
|
|
730
|
-
totalMatches: number;
|
|
731
|
-
} | {
|
|
732
|
-
reportFile: string;
|
|
733
|
-
summary: {
|
|
734
|
-
totalMatches: number;
|
|
735
|
-
};
|
|
736
|
-
}>;
|
|
879
|
+
}): Promise<SearchTranslationsResult>;
|
|
737
880
|
interface NamespaceNode {
|
|
738
881
|
keyCount: number;
|
|
739
882
|
children?: Record<string, NamespaceNode>;
|
|
@@ -770,28 +913,6 @@ declare function writeTranslations(opts: {
|
|
|
770
913
|
dryRun?: boolean;
|
|
771
914
|
projectDir?: string;
|
|
772
915
|
}): Promise<WriteTranslationsResult>;
|
|
773
|
-
/**
|
|
774
|
-
* Add new translation keys to the specified layer.
|
|
775
|
-
*
|
|
776
|
-
* @deprecated Use writeTranslations with mode: 'add' instead.
|
|
777
|
-
*/
|
|
778
|
-
declare function addTranslations(opts: {
|
|
779
|
-
layer: string;
|
|
780
|
-
translations: Record<string, Record<string, string>>;
|
|
781
|
-
dryRun?: boolean;
|
|
782
|
-
projectDir?: string;
|
|
783
|
-
}): Promise<AddTranslationsResult>;
|
|
784
|
-
/**
|
|
785
|
-
* Update existing translation keys in the specified layer.
|
|
786
|
-
*
|
|
787
|
-
* @deprecated Use writeTranslations with mode: 'update' instead.
|
|
788
|
-
*/
|
|
789
|
-
declare function updateTranslations(opts: {
|
|
790
|
-
layer: string;
|
|
791
|
-
translations: Record<string, Record<string, string>>;
|
|
792
|
-
dryRun?: boolean;
|
|
793
|
-
projectDir?: string;
|
|
794
|
-
}): Promise<UpdateTranslationsResult>;
|
|
795
916
|
/**
|
|
796
917
|
* Remove one or more translation keys from ALL locale files in the specified layer.
|
|
797
918
|
*/
|
|
@@ -802,7 +923,12 @@ declare function removeTranslations(opts: {
|
|
|
802
923
|
projectDir?: string;
|
|
803
924
|
}): Promise<RemoveTranslationsResult>;
|
|
804
925
|
/**
|
|
805
|
-
* Rename
|
|
926
|
+
* Rename a translation key across ALL locale files in one layer.
|
|
927
|
+
*
|
|
928
|
+
* Reachable on both surfaces through {@link moveTranslationKey}, which routes a
|
|
929
|
+
* same-layer request here. Kept exported because renaming within a layer is a
|
|
930
|
+
* complete operation on its own, and a programmatic caller that means exactly
|
|
931
|
+
* that should not have to express it as a move to nowhere.
|
|
806
932
|
*/
|
|
807
933
|
declare function renameTranslationKey(opts: {
|
|
808
934
|
layer: string;
|
|
@@ -821,7 +947,13 @@ declare function scaffoldLocaleFiles(opts: {
|
|
|
821
947
|
projectDir?: string;
|
|
822
948
|
}): Promise<ScaffoldLocaleResult>;
|
|
823
949
|
/**
|
|
824
|
-
* Move a key
|
|
950
|
+
* Move a key: to another layer, to another key path, or both.
|
|
951
|
+
*
|
|
952
|
+
* One entry point rather than two, because the caller's intent is "this key
|
|
953
|
+
* belongs somewhere else" and whether that somewhere else is a different layer
|
|
954
|
+
* is a detail of the project's shape, not a different operation. Omitting
|
|
955
|
+
* `toLayer` (or naming the layer the key already lives in) is a rename within
|
|
956
|
+
* the layer and routes to {@link renameTranslationKey}.
|
|
825
957
|
*
|
|
826
958
|
* Promoting an app-layer key to the shared layer once a second app needs it is
|
|
827
959
|
* a first-class operation in a layered monorepo, and composing it out of
|
|
@@ -842,13 +974,15 @@ declare function scaffoldLocaleFiles(opts: {
|
|
|
842
974
|
* silently.
|
|
843
975
|
*/
|
|
844
976
|
declare function moveTranslationKey(opts: {
|
|
845
|
-
|
|
846
|
-
|
|
977
|
+
/** Layer the key lives in today. */
|
|
978
|
+
layer: string;
|
|
847
979
|
key: string;
|
|
980
|
+
/** Layer to move it to. Omitted, or equal to `layer`, means a rename in place. */
|
|
981
|
+
toLayer?: string;
|
|
848
982
|
newKey?: string;
|
|
849
983
|
dryRun?: boolean;
|
|
850
984
|
projectDir?: string;
|
|
851
|
-
}): Promise<
|
|
985
|
+
}): Promise<MoveTranslationKeyOutcome>;
|
|
852
986
|
//# sourceMappingURL=ops-write.d.ts.map
|
|
853
987
|
//#endregion
|
|
854
988
|
//#region src/core/ops-status.d.ts
|
|
@@ -863,8 +997,13 @@ declare function moveTranslationKey(opts: {
|
|
|
863
997
|
declare function getTranslationStatus(opts: {
|
|
864
998
|
layer?: string;
|
|
865
999
|
referenceLocale?: string;
|
|
1000
|
+
/**
|
|
1001
|
+
* Also list the keys behind `summary.emptyKeys`, under `empty`. Off by
|
|
1002
|
+
* default: the count is what a health check reads, and the list grows with
|
|
1003
|
+
* the project.
|
|
1004
|
+
*/
|
|
1005
|
+
listEmpty?: boolean;
|
|
866
1006
|
projectDir?: string;
|
|
867
|
-
outputFile?: string;
|
|
868
1007
|
}): Promise<TranslationStatusResult>;
|
|
869
1008
|
//# sourceMappingURL=ops-status.d.ts.map
|
|
870
1009
|
//#endregion
|
|
@@ -950,6 +1089,10 @@ interface ScanPatternSet {
|
|
|
950
1089
|
* producing `${_}.header`-class candidates that suppress every key ending
|
|
951
1090
|
* in those segments. Language-neutral shapes (dotted literals,
|
|
952
1091
|
* trailing-dot prefixes) always run.
|
|
1092
|
+
*
|
|
1093
|
+
* Two-valued only because the two supported languages need two shape sets.
|
|
1094
|
+
* A third frontend makes this a language identifier rather than a family
|
|
1095
|
+
* flag — widen it then, and key it on the language the scanner is reading.
|
|
953
1096
|
*/
|
|
954
1097
|
bareShapes?: 'js' | 'php';
|
|
955
1098
|
}
|
|
@@ -957,7 +1100,15 @@ declare const VUE_NUXT_PATTERNS: ScanPatternSet;
|
|
|
957
1100
|
/**
|
|
958
1101
|
* Maps locale file format to the appropriate scan pattern set.
|
|
959
1102
|
* 'php-array' → Laravel (PHP translation helpers in Blade/PHP files).
|
|
960
|
-
* 'json' / undefined → Vue/Nuxt ($t / t calls in Vue/TS/JS files).
|
|
1103
|
+
* 'json' / 'yaml' / undefined → Vue/Nuxt ($t / t calls in Vue/TS/JS files).
|
|
1104
|
+
*
|
|
1105
|
+
* The locale-file format works as the key only while each format implies one
|
|
1106
|
+
* source language — 'json' and 'yaml' mean JS/TS/Vue here purely by
|
|
1107
|
+
* coincidence (a Rails project writes YAML and is not scanned by these
|
|
1108
|
+
* patterns at all), and a third language frontend writing JSON or YAML breaks
|
|
1109
|
+
* the mapping. Adding one means keying pattern sets on the language being
|
|
1110
|
+
* scanned and having callers pass that; the format would then select the IO
|
|
1111
|
+
* layer only.
|
|
961
1112
|
*/
|
|
962
1113
|
declare function getPatternSet(format?: LocaleFileFormat): ScanPatternSet;
|
|
963
1114
|
//# sourceMappingURL=patterns.d.ts.map
|
|
@@ -1005,7 +1156,18 @@ interface ScanResult {
|
|
|
1005
1156
|
* frontend reports call sites, the rules decide what they mean.
|
|
1006
1157
|
*/
|
|
1007
1158
|
|
|
1008
|
-
|
|
1159
|
+
/** What a caller can hand a scan beyond its inputs. */
|
|
1160
|
+
interface ScanSourceFilesHooks {
|
|
1161
|
+
/** Files to read, relative to `rootDir` — a {@link globSourceFiles} result, reused instead of walking the tree twice. */
|
|
1162
|
+
files?: string[];
|
|
1163
|
+
/**
|
|
1164
|
+
* Called once per file, right after it was read. `done` counts completions,
|
|
1165
|
+
* so it fires in completion order while the scan result itself stays in
|
|
1166
|
+
* input order — a counter is all that depends on the timing.
|
|
1167
|
+
*/
|
|
1168
|
+
onFile?: (done: number, total: number, file: string) => void;
|
|
1169
|
+
}
|
|
1170
|
+
declare function scanSourceFiles(rootDir: string, excludeDirs?: string[], patterns?: ScanPatternSet, frontends?: LanguageFrontend[], hooks?: ScanSourceFilesHooks): Promise<ScanResult>;
|
|
1009
1171
|
//#endregion
|
|
1010
1172
|
//#region src/core/ops-orphans.d.ts
|
|
1011
1173
|
/**
|
|
@@ -1024,7 +1186,10 @@ declare function findOrphanKeys(opts: {
|
|
|
1024
1186
|
scanDirs?: string[];
|
|
1025
1187
|
excludeDirs?: string[];
|
|
1026
1188
|
projectDir?: string;
|
|
1027
|
-
|
|
1189
|
+
/** Scanning every source file of every app takes seconds — a caller that asked for progress hears about each stride of files. */
|
|
1190
|
+
progressFn?: ProgressFn;
|
|
1191
|
+
/** Called once with the number of progress steps, before the first `progressFn` call. */
|
|
1192
|
+
onProgressTotal?: (total: number) => void;
|
|
1028
1193
|
}): Promise<FindOrphanKeysResult>;
|
|
1029
1194
|
/**
|
|
1030
1195
|
* Scan Vue/TS source files to find where translation keys are referenced.
|
|
@@ -1034,7 +1199,6 @@ declare function scanCodeUsage(opts: {
|
|
|
1034
1199
|
scanDirs?: string[];
|
|
1035
1200
|
excludeDirs?: string[];
|
|
1036
1201
|
projectDir?: string;
|
|
1037
|
-
outputFile?: string;
|
|
1038
1202
|
}): Promise<CodeUsageResult>;
|
|
1039
1203
|
/**
|
|
1040
1204
|
* Find translation keys not referenced in source code and remove them.
|
|
@@ -1047,9 +1211,10 @@ declare function removeOrphanKeys(opts: {
|
|
|
1047
1211
|
excludeDirs?: string[];
|
|
1048
1212
|
dryRun?: boolean;
|
|
1049
1213
|
projectDir?: string;
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1214
|
+
/** Same scan as {@link findOrphanKeys}, same reporting. */
|
|
1215
|
+
progressFn?: ProgressFn;
|
|
1216
|
+
/** Called once with the number of progress steps, before the first `progressFn` call. */
|
|
1217
|
+
onProgressTotal?: (total: number) => void;
|
|
1053
1218
|
}): Promise<RemoveOrphanKeysResult>;
|
|
1054
1219
|
//# sourceMappingURL=ops-orphans.d.ts.map
|
|
1055
1220
|
//#endregion
|
|
@@ -1114,7 +1279,6 @@ interface FindDuplicateKeysResult {
|
|
|
1114
1279
|
declare function findDuplicateKeys(opts?: {
|
|
1115
1280
|
locale?: string;
|
|
1116
1281
|
projectDir?: string;
|
|
1117
|
-
outputFile?: string;
|
|
1118
1282
|
/**
|
|
1119
1283
|
* Also group keys by the value they carry. Off by default: it reads every
|
|
1120
1284
|
* canonical layer rather than only the paired ones, and the existing result
|
|
@@ -1123,10 +1287,7 @@ declare function findDuplicateKeys(opts?: {
|
|
|
1123
1287
|
byValue?: boolean;
|
|
1124
1288
|
/** Shortest value worth grouping. Below it, repetition is usually legitimate. */
|
|
1125
1289
|
minValueLength?: number;
|
|
1126
|
-
}): Promise<FindDuplicateKeysResult
|
|
1127
|
-
reportFile: string;
|
|
1128
|
-
summary: FindDuplicateKeysSummary;
|
|
1129
|
-
}>;
|
|
1290
|
+
}): Promise<FindDuplicateKeysResult>;
|
|
1130
1291
|
//# sourceMappingURL=ops-duplicates.d.ts.map
|
|
1131
1292
|
//#endregion
|
|
1132
1293
|
//#region src/core/ops-check.d.ts
|
|
@@ -1155,10 +1316,26 @@ interface UncertainKeyFinding extends UndefinedKeyFinding {
|
|
|
1155
1316
|
/** Why this is not a hard finding. */
|
|
1156
1317
|
reason: string;
|
|
1157
1318
|
}
|
|
1319
|
+
/** The locale file `write` extracted the undefined keys into. */
|
|
1320
|
+
interface ExtractedUndefinedKeys {
|
|
1321
|
+
layer: string;
|
|
1322
|
+
/** The project's default locale — the source every other locale is filled from. */
|
|
1323
|
+
locale: string;
|
|
1324
|
+
/** The keys that reached the file, in alphabetical order. */
|
|
1325
|
+
keys: string[];
|
|
1326
|
+
}
|
|
1158
1327
|
interface CheckUndefinedKeysSummary {
|
|
1159
1328
|
/** Distinct statically referenced keys across all scan units. */
|
|
1160
1329
|
usedKeysChecked: number;
|
|
1330
|
+
/**
|
|
1331
|
+
* Keys that render raw at runtime, which is what the gate reads. After a
|
|
1332
|
+
* `write` run this counts the ones still undefined: an extracted key now has
|
|
1333
|
+
* a definition — an empty one — so it resolves, and `status` reports it as an
|
|
1334
|
+
* empty translation instead.
|
|
1335
|
+
*/
|
|
1161
1336
|
undefinedCount: number;
|
|
1337
|
+
/** Keys extracted into a locale file. Present only alongside `written`. */
|
|
1338
|
+
writtenCount?: number;
|
|
1162
1339
|
uncertainCount: number;
|
|
1163
1340
|
/** Unresolvable keys excluded by orphanScan ignorePatterns. */
|
|
1164
1341
|
ignoredCount: number;
|
|
@@ -1171,9 +1348,19 @@ interface CheckUndefinedKeysSummary {
|
|
|
1171
1348
|
message: string;
|
|
1172
1349
|
}
|
|
1173
1350
|
interface CheckUndefinedKeysResult {
|
|
1351
|
+
/**
|
|
1352
|
+
* The findings as the scan made them. A `write` run leaves them in place —
|
|
1353
|
+
* what was extracted is named in `written`, and the summary counts what is
|
|
1354
|
+
* left — because the call sites are what a reader has to visit either way.
|
|
1355
|
+
*/
|
|
1174
1356
|
undefinedKeys: UndefinedKeyFinding[];
|
|
1175
1357
|
uncertainKeys: UncertainKeyFinding[];
|
|
1176
1358
|
limitation: string;
|
|
1359
|
+
/**
|
|
1360
|
+
* Present only when `write` was asked for and the scan found something to
|
|
1361
|
+
* write. A clean scan reports nothing here, having written nothing.
|
|
1362
|
+
*/
|
|
1363
|
+
written?: ExtractedUndefinedKeys;
|
|
1177
1364
|
summary: CheckUndefinedKeysSummary;
|
|
1178
1365
|
}
|
|
1179
1366
|
/**
|
|
@@ -1186,6 +1373,9 @@ interface CheckUndefinedKeysResult {
|
|
|
1186
1373
|
* scopeByLayer — a unit resolves exactly the layers it vouches for). The
|
|
1187
1374
|
* graph's degenerate semantics carry over: with no app info every layer is
|
|
1188
1375
|
* resolvable everywhere, so only keys defined in NO layer are flagged.
|
|
1376
|
+
*
|
|
1377
|
+
* With `write`, the findings are also extracted into a locale file as empty
|
|
1378
|
+
* translations, which is what turns a report into the first half of the fix.
|
|
1189
1379
|
*/
|
|
1190
1380
|
declare function checkUndefinedKeys(opts?: {
|
|
1191
1381
|
locale?: string;
|
|
@@ -1195,119 +1385,362 @@ declare function checkUndefinedKeys(opts?: {
|
|
|
1195
1385
|
*/
|
|
1196
1386
|
scanDirs?: string[];
|
|
1197
1387
|
excludeDirs?: string[];
|
|
1388
|
+
/** Extract the undefined keys into a locale file. See extractUndefinedKeys. */
|
|
1389
|
+
write?: boolean;
|
|
1390
|
+
/** The layer to extract into, where the findings alone do not decide. */
|
|
1391
|
+
layer?: string;
|
|
1198
1392
|
projectDir?: string;
|
|
1199
|
-
|
|
1200
|
-
/** Also write the findings as a GitLab Code Quality JSON array to this path. */
|
|
1201
|
-
codequalityOutput?: string;
|
|
1202
|
-
}): Promise<CheckUndefinedKeysResult | {
|
|
1203
|
-
reportFile: string;
|
|
1204
|
-
summary: CheckUndefinedKeysSummary;
|
|
1205
|
-
}>;
|
|
1393
|
+
}): Promise<CheckUndefinedKeysResult>;
|
|
1206
1394
|
//# sourceMappingURL=ops-check.d.ts.map
|
|
1207
1395
|
//#endregion
|
|
1208
|
-
//#region src/
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1396
|
+
//#region src/core/codequality.d.ts
|
|
1397
|
+
interface CodeQualityIssue {
|
|
1398
|
+
description: string;
|
|
1399
|
+
check_name: string;
|
|
1400
|
+
fingerprint: string;
|
|
1401
|
+
severity: 'info' | 'minor' | 'major' | 'critical' | 'blocker';
|
|
1402
|
+
location: {
|
|
1403
|
+
path: string;
|
|
1404
|
+
lines: {
|
|
1405
|
+
begin: number;
|
|
1406
|
+
};
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* `check` findings → one issue per usage location. Uncertain findings are
|
|
1411
|
+
* not mapped: the widget has no "maybe" state, and a hard-looking finding
|
|
1412
|
+
* for an unverifiable key would train consumers to ignore the report.
|
|
1413
|
+
*/
|
|
1214
1414
|
//#endregion
|
|
1215
|
-
//#region src/
|
|
1415
|
+
//#region src/surface/types.d.ts
|
|
1416
|
+
/** Which surface is invoking an operation. They differ only in the prose they own. */
|
|
1417
|
+
type Surface = 'cli' | 'mcp';
|
|
1216
1418
|
/**
|
|
1217
|
-
*
|
|
1218
|
-
* already carries: which locale dirs are canonical (alias-free), which
|
|
1219
|
-
* layer owns an aliased dir, and which apps consume which layers.
|
|
1419
|
+
* What a parameter carries.
|
|
1220
1420
|
*
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1421
|
+
* `string[]` is a list on both surfaces: MCP passes a JSON array, the CLI a
|
|
1422
|
+
* comma-separated string it splits. `record` is the one nested shape on the
|
|
1423
|
+
* surface — the key → locale → value map `write` takes — so the builders state
|
|
1424
|
+
* its inner levels once instead of every spec carrying a schema.
|
|
1425
|
+
*/
|
|
1426
|
+
type ParamType = 'string' | 'boolean' | 'number' | 'string[]' | 'record';
|
|
1427
|
+
/** The value shape of a `record` parameter: dot-path key → locale ref → string. */
|
|
1428
|
+
type TranslationsRecord = Record<string, Record<string, string>>;
|
|
1429
|
+
interface CliParamOptions {
|
|
1430
|
+
/**
|
|
1431
|
+
* Additional spellings citty accepts for this flag. Single characters render
|
|
1432
|
+
* as `-d`; longer ones are the flag's previous name, kept working after the
|
|
1433
|
+
* descriptor took the name the MCP tool used.
|
|
1434
|
+
*/
|
|
1435
|
+
alias?: string | readonly string[];
|
|
1436
|
+
/** Not exposed as a flag. Every use of this states why in a comment. */
|
|
1437
|
+
hidden?: boolean;
|
|
1438
|
+
}
|
|
1439
|
+
interface McpParamOptions {
|
|
1440
|
+
/** Not part of the tool's input schema. Every use of this states why in a comment. */
|
|
1441
|
+
hidden?: boolean;
|
|
1442
|
+
}
|
|
1443
|
+
/** One parameter of an operation, as both surfaces expose it. */
|
|
1444
|
+
interface ParamSpec {
|
|
1445
|
+
type: ParamType;
|
|
1446
|
+
/**
|
|
1447
|
+
* The one description. It reaches `--help`, the generated CLI page and the
|
|
1448
|
+
* JSON Schema an MCP host hands its model, so it is written for a reader who
|
|
1449
|
+
* knows neither surface: no `--flag` spellings, no "this tool".
|
|
1450
|
+
*/
|
|
1451
|
+
description: string;
|
|
1452
|
+
required?: boolean;
|
|
1453
|
+
/**
|
|
1454
|
+
* Applied by the CLI so `--help` can state it. Deliberately not put into the
|
|
1455
|
+
* JSON Schema: the operations already apply their own defaults, and a schema
|
|
1456
|
+
* default would make a host send a value the caller never chose.
|
|
1457
|
+
*/
|
|
1458
|
+
default?: unknown;
|
|
1459
|
+
/** The accepted values. The CLI validates against them and MCP emits an enum. */
|
|
1460
|
+
enum?: readonly string[];
|
|
1461
|
+
/** Numbers only: reject a fractional value. */
|
|
1462
|
+
integer?: boolean;
|
|
1463
|
+
/** Numbers only: reject anything below this. */
|
|
1464
|
+
min?: number;
|
|
1465
|
+
/** `string[]` parameters that also accept the literal "all". */
|
|
1466
|
+
allowAll?: boolean;
|
|
1467
|
+
cli?: CliParamOptions;
|
|
1468
|
+
mcp?: McpParamOptions;
|
|
1469
|
+
}
|
|
1470
|
+
type Params = Record<string, ParamSpec>;
|
|
1471
|
+
/**
|
|
1472
|
+
* A CI gate a command evaluates. `counter` is the field of `result.summary`
|
|
1473
|
+
* carrying the observed value.
|
|
1224
1474
|
*
|
|
1225
|
-
*
|
|
1475
|
+
* The two shapes are a union rather than one type with optional halves so the
|
|
1476
|
+
* invariants hold at compile time: a flagged gate always has a flag to read
|
|
1477
|
+
* its name and threshold from, and a flagless one always carries both itself.
|
|
1478
|
+
* Stated as options, `{ counter, threshold }` type-checks and then has no name
|
|
1479
|
+
* to report the gate under.
|
|
1480
|
+
*/
|
|
1481
|
+
type GateSpec = FlaggedGateSpec | AlwaysOnGateSpec;
|
|
1482
|
+
interface GateSpecBase {
|
|
1483
|
+
counter: string;
|
|
1484
|
+
/** 'above' trips when observed > threshold (default); 'below' when observed < threshold. */
|
|
1485
|
+
direction?: 'above' | 'below';
|
|
1486
|
+
}
|
|
1487
|
+
/**
|
|
1488
|
+
* Requested by a flag, and evaluated only when that flag is passed. Omitting
|
|
1489
|
+
* `threshold` takes it from the flag's own value, so a boolean flag pairs with
|
|
1490
|
+
* `threshold: 0` and a numeric one (`--failUnder 90`) omits it.
|
|
1491
|
+
*/
|
|
1492
|
+
interface FlaggedGateSpec extends GateSpecBase {
|
|
1493
|
+
flag: string;
|
|
1494
|
+
name?: never;
|
|
1495
|
+
threshold?: number;
|
|
1496
|
+
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Always evaluated, for findings that are a defect rather than a threshold — a
|
|
1499
|
+
* key that renders raw in production is not something you opt into caring
|
|
1500
|
+
* about. It still reports as a gate: the run succeeded, and what it found is
|
|
1501
|
+
* what you are being told about.
|
|
1502
|
+
*/
|
|
1503
|
+
interface AlwaysOnGateSpec extends GateSpecBase {
|
|
1504
|
+
flag?: never;
|
|
1505
|
+
name: string;
|
|
1506
|
+
threshold: number;
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* What the surface hands a report builder beyond the result: the project the
|
|
1510
|
+
* operation ran against and the arguments it ran with.
|
|
1511
|
+
*/
|
|
1512
|
+
interface ReportContext<A = Record<string, unknown>> {
|
|
1513
|
+
projectDir: string;
|
|
1514
|
+
/** The project's resolved i18n configuration, as the operation itself read it. */
|
|
1515
|
+
config: I18nConfig;
|
|
1516
|
+
/** The operation's arguments, as the surface resolved them. */
|
|
1517
|
+
args: A;
|
|
1518
|
+
}
|
|
1519
|
+
/**
|
|
1520
|
+
* How a result too large to hand back is diverted to a file.
|
|
1226
1521
|
*
|
|
1227
|
-
*
|
|
1228
|
-
*
|
|
1522
|
+
* An operation always returns its whole result. Whether that result is written
|
|
1523
|
+
* to disk and replaced by a compact stand-in is the surface's decision — it is
|
|
1524
|
+
* the surface that owns `outputFile`, the configured report directory and the
|
|
1525
|
+
* name the file is written under — so the operations know nothing about any of
|
|
1526
|
+
* it, and a descriptor declaring this is what gives an operation the parameters
|
|
1527
|
+
* that request it.
|
|
1528
|
+
*/
|
|
1529
|
+
interface ReportSpec<R = unknown, A = Record<string, unknown>> {
|
|
1530
|
+
/**
|
|
1531
|
+
* The file's base name under the configured report directory, and the tool
|
|
1532
|
+
* name recorded inside the report. A function where one operation answers
|
|
1533
|
+
* different questions and writes each under its own name — pipelines archive
|
|
1534
|
+
* these paths, so they are part of the contract.
|
|
1535
|
+
*/
|
|
1536
|
+
name: string | ((args: A) => string);
|
|
1537
|
+
/** The compact stand-in returned once the full result is on disk. */
|
|
1538
|
+
summary: (result: R) => unknown;
|
|
1539
|
+
/**
|
|
1540
|
+
* The `outputFile` parameter as this operation offers it. Declared here and
|
|
1541
|
+
* nowhere else, so an operation cannot advertise the parameter without the
|
|
1542
|
+
* plumbing behind it, nor grow the plumbing without the parameter.
|
|
1543
|
+
*/
|
|
1544
|
+
outputFile: {
|
|
1545
|
+
/** The example path its description carries. */
|
|
1546
|
+
example: string;
|
|
1547
|
+
cli?: CliParamOptions;
|
|
1548
|
+
mcp?: McpParamOptions;
|
|
1549
|
+
};
|
|
1550
|
+
/** The same findings, as a GitLab Code Quality report the pipeline collects. */
|
|
1551
|
+
codequality?: {
|
|
1552
|
+
/** What the findings are called in the parameter's description. */
|
|
1553
|
+
findings: string;
|
|
1554
|
+
/**
|
|
1555
|
+
* Returning undefined writes nothing, which is not the same as writing an
|
|
1556
|
+
* empty array: the empty array is the baseline the merge-request widget
|
|
1557
|
+
* diffs against, so it is only right for a run that looked for these
|
|
1558
|
+
* findings and found none.
|
|
1559
|
+
*/
|
|
1560
|
+
issues: (result: R, ctx: ReportContext<A>) => CodeQualityIssue[] | undefined;
|
|
1561
|
+
};
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* A report spec with its result type erased, as the runner sees it.
|
|
1229
1565
|
*
|
|
1230
|
-
*
|
|
1231
|
-
*
|
|
1232
|
-
*
|
|
1233
|
-
* *every* canonical layer — with no ownership information, every
|
|
1234
|
-
* layer's keys must be treated as globally visible.
|
|
1235
|
-
* - **Single-app config** (generic/Laravel/Vue/React adapters, or a Nuxt
|
|
1236
|
-
* project with one app): the strict definition applies, so
|
|
1237
|
-
* `sharedLayers` is empty (no layer is consumed by more than one app)
|
|
1238
|
-
* and `appsUsingLayer` returns that one app for the layers it consumes.
|
|
1239
|
-
* Per-layer scope then equals the whole project, which is correct.
|
|
1240
|
-
* - **Canonical layer consumed by no app** (in a multi-app config):
|
|
1241
|
-
* `appsUsingLayer` returns `[]` and the layer is not in `sharedLayers`.
|
|
1242
|
-
* Callers should treat such layers conservatively (global scope).
|
|
1566
|
+
* `any` rather than `unknown`: the runner holds a result whose type it cannot
|
|
1567
|
+
* know, while every declaration site is checked against its own operation's
|
|
1568
|
+
* result type.
|
|
1243
1569
|
*/
|
|
1244
|
-
|
|
1570
|
+
type AnyReportSpec = ReportSpec<any>;
|
|
1571
|
+
/** How the MCP server advertises an operation as a tool. */
|
|
1572
|
+
interface McpToolSpec {
|
|
1573
|
+
name: string;
|
|
1574
|
+
/** The display title a host shows. */
|
|
1575
|
+
title: string;
|
|
1576
|
+
/** Behaviour hints a host reads. Only the translating tools declare any. */
|
|
1577
|
+
annotations?: {
|
|
1578
|
+
title?: string;
|
|
1579
|
+
readOnlyHint?: boolean;
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
/** How the CLI exposes an operation as a command. */
|
|
1583
|
+
interface CliCommandSpec {
|
|
1584
|
+
name: string;
|
|
1585
|
+
}
|
|
1586
|
+
/**
|
|
1587
|
+
* What a surface hands an operation beyond its parameters.
|
|
1588
|
+
*
|
|
1589
|
+
* `surface` exists because the guidance an agent-mode result carries is the
|
|
1590
|
+
* caller's, not the operation's: a terminal is told to pass `--provider`, a
|
|
1591
|
+
* host is told to translate the fallback contexts inline. Keeping both strings
|
|
1592
|
+
* in one place is the point — they used to sit in two files and say different
|
|
1593
|
+
* things about the same state.
|
|
1594
|
+
*/
|
|
1595
|
+
interface OperationContext {
|
|
1596
|
+
surface: Surface;
|
|
1597
|
+
/** Provider-backed translation, when the surface resolved one. */
|
|
1598
|
+
translateFn?: TranslateFn;
|
|
1245
1599
|
/**
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1600
|
+
* Progress reporting, when the caller asked for it. Only MCP does — a
|
|
1601
|
+
* terminal is left with its exit code. The operations that take long enough
|
|
1602
|
+
* to report call it (translating, orphan scans); the rest never do.
|
|
1248
1603
|
*/
|
|
1249
|
-
|
|
1604
|
+
progressFn?: ProgressFn;
|
|
1250
1605
|
/**
|
|
1251
|
-
*
|
|
1252
|
-
*
|
|
1253
|
-
*
|
|
1254
|
-
* names unknown to `localeDirs` (e.g. layers without locale dirs).
|
|
1606
|
+
* The number of steps the operation is about to report, counted in whatever
|
|
1607
|
+
* unit it reports in. Called once, before the first `progressFn` call, so a
|
|
1608
|
+
* notification never goes out against an unknown total.
|
|
1255
1609
|
*/
|
|
1256
|
-
|
|
1610
|
+
onProgressTotal?: (total: number) => void;
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* The value of one parameter as the operation receives it: already split,
|
|
1614
|
+
* parsed and validated by whichever surface took it.
|
|
1615
|
+
*/
|
|
1616
|
+
type ParamValue<S extends ParamSpec> = S extends {
|
|
1617
|
+
type: 'boolean';
|
|
1618
|
+
} ? boolean : S extends {
|
|
1619
|
+
type: 'number';
|
|
1620
|
+
} ? number : S extends {
|
|
1621
|
+
type: 'record';
|
|
1622
|
+
} ? TranslationsRecord : S extends {
|
|
1623
|
+
type: 'string[]';
|
|
1624
|
+
allowAll: true;
|
|
1625
|
+
} ? string[] | 'all' : S extends {
|
|
1626
|
+
type: 'string[]';
|
|
1627
|
+
} ? string[] : S extends {
|
|
1628
|
+
type: 'string';
|
|
1629
|
+
enum: readonly (infer E extends string)[];
|
|
1630
|
+
} ? E : S extends {
|
|
1631
|
+
type: 'string';
|
|
1632
|
+
} ? string : never;
|
|
1633
|
+
type RequiredParamNames<P extends Params> = { [K in keyof P]-?: P[K] extends {
|
|
1634
|
+
required: true;
|
|
1635
|
+
} ? K : never }[keyof P];
|
|
1636
|
+
/**
|
|
1637
|
+
* The arguments an operation's `run` receives. Required parameters are present,
|
|
1638
|
+
* the rest are optional, and `projectDir` is always available because both
|
|
1639
|
+
* surfaces resolve it themselves (the CLI from `--projectDir`, the server from
|
|
1640
|
+
* I18N_PROJECT_DIR) rather than making every operation declare it.
|
|
1641
|
+
*/
|
|
1642
|
+
type OperationArgs<P extends Params = Params> = { [K in RequiredParamNames<P> & keyof P]: ParamValue<P[K]> } & { [K in Exclude<keyof P, RequiredParamNames<P>>]?: ParamValue<P[K]> } & {
|
|
1643
|
+
projectDir?: string;
|
|
1644
|
+
};
|
|
1645
|
+
/** One operation, as both surfaces read it. */
|
|
1646
|
+
interface OperationDescriptor<P extends Params = Params> {
|
|
1647
|
+
/** Stable identifier, independent of what either surface calls it. */
|
|
1648
|
+
id: string;
|
|
1649
|
+
/** Null for an operation the CLI does not expose. */
|
|
1650
|
+
cli: CliCommandSpec | null;
|
|
1651
|
+
/** Null for an operation the MCP server does not advertise. */
|
|
1652
|
+
mcp: McpToolSpec | null;
|
|
1653
|
+
/** One sentence, on both surfaces. */
|
|
1654
|
+
description: string;
|
|
1257
1655
|
/**
|
|
1258
|
-
*
|
|
1259
|
-
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1656
|
+
* Further prose for a model deciding whether to call the tool: when to reach
|
|
1657
|
+
* for it, what the result carries, what it will not do. MCP only — a `--help`
|
|
1658
|
+
* line has to stay a line, and the generated CLI page says the same things in
|
|
1659
|
+
* its flag table.
|
|
1262
1660
|
*/
|
|
1263
|
-
|
|
1661
|
+
longDescription?: string;
|
|
1662
|
+
params: P;
|
|
1663
|
+
/** CI gates the CLI evaluates. Exit codes are a CLI notion, so MCP ignores these. */
|
|
1664
|
+
gates?: GateSpec[];
|
|
1264
1665
|
/**
|
|
1265
|
-
*
|
|
1266
|
-
*
|
|
1267
|
-
*
|
|
1268
|
-
*
|
|
1666
|
+
* The operation translates, so the surface has to hand it a backend: the CLI
|
|
1667
|
+
* resolves one from the provider flags, the server from its startup
|
|
1668
|
+
* environment. Without one the operation returns contexts to translate by
|
|
1669
|
+
* hand rather than failing.
|
|
1269
1670
|
*/
|
|
1270
|
-
|
|
1671
|
+
usesTranslateFn?: boolean;
|
|
1271
1672
|
/**
|
|
1272
|
-
*
|
|
1273
|
-
*
|
|
1274
|
-
*
|
|
1673
|
+
* The result is large enough to be worth writing to a file instead of
|
|
1674
|
+
* returning. Declaring this is what adds the parameters that request it and
|
|
1675
|
+
* what makes the configured report directory apply to the operation.
|
|
1676
|
+
*
|
|
1677
|
+
* The result type stays open: a `run` whose parameters are contextually typed
|
|
1678
|
+
* is not an inference site, so nothing here can see the operation's own
|
|
1679
|
+
* result type. Declaration sites annotate it on the builder instead, which is
|
|
1680
|
+
* what type-checks them.
|
|
1275
1681
|
*/
|
|
1276
|
-
|
|
1682
|
+
report?: ReportSpec<any, OperationArgs<P>>;
|
|
1683
|
+
/**
|
|
1684
|
+
* Declared as a method so the table can hold descriptors with different
|
|
1685
|
+
* parameter maps: method parameters are compared bivariantly, which is what
|
|
1686
|
+
* lets `run` be typed against each operation's own arguments and still be
|
|
1687
|
+
* callable through the erased element type below.
|
|
1688
|
+
*/
|
|
1689
|
+
run(args: OperationArgs<P>, ctx: OperationContext): Promise<unknown>;
|
|
1277
1690
|
}
|
|
1278
1691
|
/**
|
|
1279
|
-
*
|
|
1280
|
-
*
|
|
1692
|
+
* A descriptor as the registrars see it, with `run` erased to plain arguments.
|
|
1693
|
+
* They build those arguments from a schema at runtime and cannot know the
|
|
1694
|
+
* per-operation type, so the erasure happens once, in `defineOperation`,
|
|
1695
|
+
* instead of at every call site.
|
|
1281
1696
|
*/
|
|
1282
|
-
|
|
1697
|
+
type AnyOperationDescriptor = Omit<OperationDescriptor<Params>, 'run' | 'params' | 'report'> & {
|
|
1698
|
+
params: Params;
|
|
1699
|
+
report?: AnyReportSpec;
|
|
1700
|
+
run(args: Record<string, unknown>, ctx: OperationContext): Promise<unknown>;
|
|
1701
|
+
};
|
|
1283
1702
|
/**
|
|
1284
|
-
*
|
|
1703
|
+
* Declare one operation. The `const` type parameter is what keeps `required:
|
|
1704
|
+
* true` and `enum: [...]` literal, so `run` receives `layer: string` rather
|
|
1705
|
+
* than `string | undefined` for a parameter the surface guarantees.
|
|
1285
1706
|
*
|
|
1286
|
-
*
|
|
1287
|
-
*
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1707
|
+
* An operation that declares a `report` gains the parameters that request one
|
|
1708
|
+
* here, so the two cannot drift apart.
|
|
1709
|
+
*/
|
|
1710
|
+
//#endregion
|
|
1711
|
+
//#region src/surface/descriptors.d.ts
|
|
1712
|
+
/**
|
|
1713
|
+
* Registry order: it is the order `the-i18n-cli --help` lists commands in and
|
|
1714
|
+
* the order both generated reference overviews are written in.
|
|
1715
|
+
*/
|
|
1716
|
+
declare const descriptors: readonly AnyOperationDescriptor[];
|
|
1717
|
+
/** The descriptors a surface exposes, in registry order. */
|
|
1718
|
+
declare function descriptorsFor(surface: 'cli' | 'mcp'): AnyOperationDescriptor[];
|
|
1719
|
+
/** The parameter names a surface exposes for one operation, in declaration order. */
|
|
1720
|
+
declare function visibleParams(descriptor: AnyOperationDescriptor, surface: 'cli' | 'mcp'): string[];
|
|
1721
|
+
//# sourceMappingURL=descriptors.d.ts.map
|
|
1722
|
+
|
|
1723
|
+
//#endregion
|
|
1724
|
+
//#region src/surface/report.d.ts
|
|
1725
|
+
/**
|
|
1726
|
+
* Write the result where the caller asked for it, and hand back the compact
|
|
1727
|
+
* stand-in — or hand back the result untouched when nothing asked for a file.
|
|
1291
1728
|
*
|
|
1292
|
-
*
|
|
1293
|
-
*
|
|
1294
|
-
* a config with no app info reports *every* canonical layer as shared, and a
|
|
1295
|
-
* layer no app consumes appears in `consumers` with an empty array rather than
|
|
1296
|
-
* being left out. Absent and "none" must not look alike here.
|
|
1729
|
+
* Called with the arguments the operation ran with, which is what lets an
|
|
1730
|
+
* operation answering several questions write each under its own report name.
|
|
1297
1731
|
*/
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
//# sourceMappingURL=layer-graph.d.ts.map
|
|
1732
|
+
declare function divertToReport(result: unknown, descriptor: AnyOperationDescriptor, args: Record<string, unknown>): Promise<unknown>;
|
|
1733
|
+
//# sourceMappingURL=report.d.ts.map
|
|
1734
|
+
//#endregion
|
|
1735
|
+
//#region src/config/cache.d.ts
|
|
1736
|
+
/** The most recently resolved config, or null when nothing has been resolved. */
|
|
1737
|
+
declare function getCachedConfig(): I18nConfig | null;
|
|
1738
|
+
declare function clearConfigCache(): void;
|
|
1739
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
1740
|
+
//#endregion
|
|
1741
|
+
//#region src/config/detector.d.ts
|
|
1742
|
+
declare function detectI18nConfig(projectDir: string): Promise<I18nConfig>;
|
|
1743
|
+
//# sourceMappingURL=detector.d.ts.map
|
|
1311
1744
|
//#endregion
|
|
1312
1745
|
//#region src/scanner/frontends/oxc.d.ts
|
|
1313
1746
|
declare function createOxcFrontend(): LanguageFrontend;
|
|
@@ -1382,25 +1815,6 @@ declare class ToolError extends Error {
|
|
|
1382
1815
|
}
|
|
1383
1816
|
//# sourceMappingURL=errors.d.ts.map
|
|
1384
1817
|
//#endregion
|
|
1385
|
-
//#region src/utils/rename-notice.d.ts
|
|
1386
|
-
/**
|
|
1387
|
-
* The kit is renaming to the `@the-i18n-kit` scope (#315). During the window
|
|
1388
|
-
* both names publish from one source at matching versions, so nothing breaks —
|
|
1389
|
-
* but a user on the old name has no way of learning that unless the package
|
|
1390
|
-
* tells them.
|
|
1391
|
-
*
|
|
1392
|
-
* A package finds out it is the old one by reading its own `name` at runtime,
|
|
1393
|
-
* which is why this takes the name rather than deciding for itself: the same
|
|
1394
|
-
* code ships under both names, and only the manifest differs.
|
|
1395
|
-
*/
|
|
1396
|
-
/**
|
|
1397
|
-
* The notice for a package running under a legacy name, or null when it is
|
|
1398
|
-
* already running under its new one — which is the case that must stay silent,
|
|
1399
|
-
* since a notice there would be telling people to do what they have done.
|
|
1400
|
-
*/
|
|
1401
|
-
declare function renameNotice(packageName: string): string | null;
|
|
1402
|
-
//# sourceMappingURL=rename-notice.d.ts.map
|
|
1403
|
-
//#endregion
|
|
1404
1818
|
//#region src/llm/providers.d.ts
|
|
1405
1819
|
type LlmProvider = 'openai' | 'anthropic' | 'google';
|
|
1406
1820
|
/** How a provider failure should be handled by the caller. */
|
|
@@ -1419,7 +1833,7 @@ declare class TranslateProviderError extends Error {
|
|
|
1419
1833
|
constructor(message: string, kind: TranslateProviderErrorKind, status?: number);
|
|
1420
1834
|
}
|
|
1421
1835
|
/**
|
|
1422
|
-
* Classify
|
|
1836
|
+
* Classify a provider error into a TranslateProviderError:
|
|
1423
1837
|
* 401/403 → auth, 429 → rate-limit, anything else → provider.
|
|
1424
1838
|
* Already-classified errors pass through unchanged.
|
|
1425
1839
|
*/
|
|
@@ -1451,8 +1865,9 @@ declare function resolveProviderBaseUrl(sources: {
|
|
|
1451
1865
|
config?: string;
|
|
1452
1866
|
}): string | undefined;
|
|
1453
1867
|
/**
|
|
1454
|
-
* Create a TranslateFn from an LLM provider config.
|
|
1455
|
-
*
|
|
1868
|
+
* Create a TranslateFn from an LLM provider config. Every provider is called
|
|
1869
|
+
* over plain HTTP, so nothing beyond the CLI has to be installed.
|
|
1870
|
+
* Throws if the API key is missing.
|
|
1456
1871
|
*/
|
|
1457
1872
|
declare function createTranslateFn(config: LlmProviderConfig): Promise<TranslateFn>;
|
|
1458
1873
|
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -1474,5 +1889,5 @@ declare function loadProjectConfig(projectDir: string): Promise<ProjectConfig |
|
|
|
1474
1889
|
//# sourceMappingURL=project-config.d.ts.map
|
|
1475
1890
|
|
|
1476
1891
|
//#endregion
|
|
1477
|
-
export {
|
|
1478
|
-
//# sourceMappingURL=index-
|
|
1892
|
+
export { type AnyOperationDescriptor, type AnyReportSpec, BASE_URL_ENV, type CallArgument, type CallSite, type CheckUndefinedKeysResult, type CheckUndefinedKeysSummary, CodeUsageRef, CodeUsageResult, DescribeProjectResult, type DuplicateKeyCollision, DynamicKeyRef, EmptyTranslationsResult, type FileEvidence, type FindDuplicateKeysResult, type FindDuplicateKeysSummary, FindOrphanKeysResult, GeneratedProjectConfig, type I18nConfig, type I18nKitConfig, InitProjectConfigResult, type KeyUsageLocation, LARAVEL_PATTERNS, type LanguageFrontend, type LayerGraph, LayerStatus, type LlmProvider, type LlmProviderConfig, type LocaleDefinition, type LocaleDir, LocaleDirInfo, type LocaleRefAmbiguity, LocaleRefInfo, LocaleStatus, MisplacedUsageRef, MissingTranslationsResult, MoveTranslationKeyOutcome, MoveTranslationKeyPlanEntry, MoveTranslationKeyResult, MutationPreview, MutationResult, type OperationContext, type OperationDescriptor, type ParamSpec, type ParamType, type Params, PlaceholderValidationIssue, PlaceholderValidationResult, ProgressFn, type ProjectConfig, RemoveOrphanKeysResult, RemoveTranslationsPreview, RemoveTranslationsResult, RenameTranslationKeyPreview, RenameTranslationKeyResult, type ReportContext, type ReportSpec, ScaffoldLocaleFileInfo, ScaffoldLocaleResult, ScanCodeUsageResult, type ScanResult, SearchMatch, SearchTranslationsResult, type SerializedLayerGraph, type Surface, ToolError, TranslateAllLayersResult, TranslateAllLayersSummary, TranslateFailReason, TranslateFn, TranslateKeyLocaleIssue, TranslateKeyResult, TranslateKeySkip, TranslateLayerTotals, TranslateMissingCompactEntry, TranslateMissingLocaleResult, TranslateMissingOptions, TranslateMissingOutcome, TranslateMissingResult, TranslateMode, TranslateProviderError, type TranslateProviderErrorKind, TranslateRequest, TranslateResponse, TranslateSkipReason, TranslationStatusResult, TranslationStatusSummary, type TranslationsRecord, type UncertainKeyFinding, type UndefinedKeyFinding, UnresolvedKeyWarningRef, UnresolvedLocaleRef, VUE_NUXT_PATTERNS, WriteTranslationsResult, buildLayerGraph, checkUndefinedKeys, classifyProviderError, clearConfigCache, createBladeFrontend, createOxcFrontend, createPatternsFrontend, createPhpFrontend, createTranslateFn, defineI18nKitConfig, describeProject, descriptors, descriptorsFor, detectConfig, detectI18nConfig, divertToReport, findDuplicateKeys, findEmptyTranslations, findLocaleImpl, findOrphanKeys, getCachedConfig, getMissingTranslations, getPatternSet, getTranslationStatus, getTranslations, listLocaleDirs, listNamespaces, loadProjectConfig, moveTranslationKey, readLocaleData, removeOrphanKeys, removeTranslations, renameTranslationKey, resolveProtectedLocales, resolveProviderBaseUrl, scaffoldLocaleFiles, scanCodeUsage, scanSourceFiles, searchTranslations, serializeLayerGraph, toErrorMessage, translateKey, translateMissing, visibleParams, writeTranslations };
|
|
1893
|
+
//# sourceMappingURL=index-CdjJ71Ag.d.ts.map
|