@verbatra/sdk 0.6.0 → 0.6.2
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 +1 -1
- package/dist/index.cjs +1338 -279
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +350 -70
- package/dist/index.d.ts +350 -70
- package/dist/index.js +1338 -280
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -231,10 +231,81 @@ declare const supportedFormatSchema$1: z.ZodEnum<{
|
|
|
231
231
|
xliff: "xliff";
|
|
232
232
|
yaml: "yaml";
|
|
233
233
|
arb: "arb";
|
|
234
|
+
properties: "properties";
|
|
234
235
|
}>;
|
|
235
236
|
/** One of the supported source formats; a member of {@link SUPPORTED_FORMATS}. */
|
|
236
237
|
type SupportedFormat$1 = z.infer<typeof supportedFormatSchema$1>;
|
|
237
238
|
|
|
239
|
+
/** Outcome of a bounded read: the content, or why it could not be read in bounds. */
|
|
240
|
+
type BoundedFileRead = {
|
|
241
|
+
readonly kind: "ok";
|
|
242
|
+
readonly content: string;
|
|
243
|
+
} | {
|
|
244
|
+
readonly kind: "missing";
|
|
245
|
+
} | {
|
|
246
|
+
readonly kind: "too-large";
|
|
247
|
+
};
|
|
248
|
+
/** Outcome of a bounded binary read: the bytes, or why they could not be read in bounds. */
|
|
249
|
+
type BoundedBytesRead = {
|
|
250
|
+
readonly kind: "ok";
|
|
251
|
+
readonly bytes: Uint8Array;
|
|
252
|
+
} | {
|
|
253
|
+
readonly kind: "missing";
|
|
254
|
+
} | {
|
|
255
|
+
readonly kind: "too-large";
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* The minimal file-system surface the SDK needs. Reads are bounded and writes are atomic. Injectable so
|
|
259
|
+
* tests stay deterministic; the format adapters do their own file IO and bypass this seam.
|
|
260
|
+
*/
|
|
261
|
+
interface SdkFs {
|
|
262
|
+
/** Whether a readable file exists at the path. */
|
|
263
|
+
fileExists(path: string): Promise<boolean>;
|
|
264
|
+
/**
|
|
265
|
+
* Read a file as UTF-8 through a single handle, bounded to maxBytes. TOCTOU-safe: the handle is
|
|
266
|
+
* fstat'd and the read never advances past the sized length, so swapping in a larger file cannot
|
|
267
|
+
* bypass the cap. A missing or unreadable path is "missing"; a file over the cap is "too-large".
|
|
268
|
+
*/
|
|
269
|
+
readFileBounded(path: string, maxBytes: number): Promise<BoundedFileRead>;
|
|
270
|
+
/** Read a file as raw bytes with the same TOCTOU-safe, bounded discipline as {@link readFileBounded}. */
|
|
271
|
+
readBytesBounded(path: string, maxBytes: number): Promise<BoundedBytesRead>;
|
|
272
|
+
/** Write atomically: a temp file in the same directory, then rename over the target. */
|
|
273
|
+
writeFile(path: string, data: string): Promise<void>;
|
|
274
|
+
/** Write raw bytes atomically (temp file, then rename over the target). Used for the workbook. */
|
|
275
|
+
writeBytes(path: string, data: Uint8Array): Promise<void>;
|
|
276
|
+
/**
|
|
277
|
+
* Atomically create a file only if it does not already exist (O_EXCL semantics), creating any
|
|
278
|
+
* missing parent directory first. Returns true if this call created the file, false if a file
|
|
279
|
+
* was already present (no write performed). The backbone of {@link withLocaleWriteLock}'s
|
|
280
|
+
* exclusive-create lock: the parent-directory creation lives here so that primitive never touches
|
|
281
|
+
* `node:fs` directly and a fake `SdkFs` in tests never needs a real directory to exist.
|
|
282
|
+
*/
|
|
283
|
+
createExclusive(path: string, data: string): Promise<boolean>;
|
|
284
|
+
/** Delete a file if present; a no-op if it is already absent. */
|
|
285
|
+
deleteFile(path: string): Promise<void>;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* The content-addressed translation-memory (TM) cache: a local, gitignored, regenerable sidecar to
|
|
290
|
+
* the lock file (`verbatra.cache.json`). It lets a translation whose source content is unchanged be
|
|
291
|
+
* reused for free, even under a renamed key or across two keys with byte-identical source text,
|
|
292
|
+
* instead of being re-sent to the provider.
|
|
293
|
+
*
|
|
294
|
+
* Nesting is `entries[fingerprint][targetLocale][contentHash] = value`. The fingerprint scopes every
|
|
295
|
+
* entry to one translation context (provider, model, tone, glossary), so a tone or glossary change
|
|
296
|
+
* never serves a stale value. Unlike the lock file, a corrupt or wrong-version cache degrades to an
|
|
297
|
+
* empty cache and never fails a run: it is a cost optimization, not a correctness record.
|
|
298
|
+
*/
|
|
299
|
+
interface TranslationMemory {
|
|
300
|
+
/** The cache schema version; a value this build does not recognize degrades the whole file to empty. */
|
|
301
|
+
readonly version: number;
|
|
302
|
+
/** Cached values, nested fingerprint to target locale to source content hash to translated value. */
|
|
303
|
+
readonly entries: Readonly<Record<string, Readonly<Record<string, Readonly<Record<string, string>>>>>>;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** The cache file's name, a sibling of the lock file and obviously JSON. */
|
|
307
|
+
declare const CACHE_FILE_NAME = "verbatra.cache.json";
|
|
308
|
+
|
|
238
309
|
/**
|
|
239
310
|
* The provider section of the config: a discriminated union over the provider id, reusing each
|
|
240
311
|
* provider's own config schema. There is no key field anywhere in this union except
|
|
@@ -246,23 +317,27 @@ declare const providerConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
246
317
|
options: z.ZodObject<{
|
|
247
318
|
model: z.ZodString;
|
|
248
319
|
maxTokens: z.ZodNumber;
|
|
320
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
249
321
|
}, z.core.$strict>;
|
|
250
322
|
}, z.core.$strip>, z.ZodObject<{
|
|
251
323
|
id: z.ZodLiteral<"openai">;
|
|
252
324
|
options: z.ZodObject<{
|
|
253
325
|
model: z.ZodString;
|
|
254
326
|
maxOutputTokens: z.ZodNumber;
|
|
327
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
255
328
|
}, z.core.$strict>;
|
|
256
329
|
}, z.core.$strip>, z.ZodObject<{
|
|
257
330
|
id: z.ZodLiteral<"gemini">;
|
|
258
331
|
options: z.ZodObject<{
|
|
259
332
|
model: z.ZodString;
|
|
260
333
|
maxOutputTokens: z.ZodNumber;
|
|
334
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
261
335
|
}, z.core.$strict>;
|
|
262
336
|
}, z.core.$strip>, z.ZodObject<{
|
|
263
337
|
id: z.ZodLiteral<"deepl">;
|
|
264
338
|
options: z.ZodObject<{
|
|
265
339
|
glossaryId: z.ZodOptional<z.ZodString>;
|
|
340
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
266
341
|
}, z.core.$strict>;
|
|
267
342
|
}, z.core.$strip>, z.ZodObject<{
|
|
268
343
|
id: z.ZodLiteral<"openai-compatible">;
|
|
@@ -271,6 +346,7 @@ declare const providerConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
271
346
|
model: z.ZodString;
|
|
272
347
|
maxOutputTokens: z.ZodNumber;
|
|
273
348
|
apiKeyEnvVar: z.ZodOptional<z.ZodString>;
|
|
349
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
274
350
|
}, z.core.$strict>;
|
|
275
351
|
}, z.core.$strip>], "id">;
|
|
276
352
|
/** One validated provider section: the provider id plus that provider's own options. */
|
|
@@ -294,6 +370,7 @@ declare const verbatraConfigSchema: z.ZodObject<{
|
|
|
294
370
|
xliff: "xliff";
|
|
295
371
|
yaml: "yaml";
|
|
296
372
|
arb: "arb";
|
|
373
|
+
properties: "properties";
|
|
297
374
|
}>;
|
|
298
375
|
files: z.ZodObject<{
|
|
299
376
|
pattern: z.ZodString;
|
|
@@ -303,23 +380,27 @@ declare const verbatraConfigSchema: z.ZodObject<{
|
|
|
303
380
|
options: z.ZodObject<{
|
|
304
381
|
model: z.ZodString;
|
|
305
382
|
maxTokens: z.ZodNumber;
|
|
383
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
306
384
|
}, z.core.$strict>;
|
|
307
385
|
}, z.core.$strip>, z.ZodObject<{
|
|
308
386
|
id: z.ZodLiteral<"openai">;
|
|
309
387
|
options: z.ZodObject<{
|
|
310
388
|
model: z.ZodString;
|
|
311
389
|
maxOutputTokens: z.ZodNumber;
|
|
390
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
312
391
|
}, z.core.$strict>;
|
|
313
392
|
}, z.core.$strip>, z.ZodObject<{
|
|
314
393
|
id: z.ZodLiteral<"gemini">;
|
|
315
394
|
options: z.ZodObject<{
|
|
316
395
|
model: z.ZodString;
|
|
317
396
|
maxOutputTokens: z.ZodNumber;
|
|
397
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
318
398
|
}, z.core.$strict>;
|
|
319
399
|
}, z.core.$strip>, z.ZodObject<{
|
|
320
400
|
id: z.ZodLiteral<"deepl">;
|
|
321
401
|
options: z.ZodObject<{
|
|
322
402
|
glossaryId: z.ZodOptional<z.ZodString>;
|
|
403
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
323
404
|
}, z.core.$strict>;
|
|
324
405
|
}, z.core.$strip>, z.ZodObject<{
|
|
325
406
|
id: z.ZodLiteral<"openai-compatible">;
|
|
@@ -328,6 +409,7 @@ declare const verbatraConfigSchema: z.ZodObject<{
|
|
|
328
409
|
model: z.ZodString;
|
|
329
410
|
maxOutputTokens: z.ZodNumber;
|
|
330
411
|
apiKeyEnvVar: z.ZodOptional<z.ZodString>;
|
|
412
|
+
requestTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
331
413
|
}, z.core.$strict>;
|
|
332
414
|
}, z.core.$strip>], "id">;
|
|
333
415
|
glossary: z.ZodOptional<z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodString>, z.ZodString]>>;
|
|
@@ -435,55 +517,6 @@ declare function defineConfig(config: AuthoringConfigFor<"gemini">): VerbatraCon
|
|
|
435
517
|
declare function defineConfig(config: AuthoringConfigFor<"deepl">): VerbatraConfigInput;
|
|
436
518
|
declare function defineConfig(config: AuthoringConfig): VerbatraConfigInput;
|
|
437
519
|
|
|
438
|
-
/** Outcome of a bounded read: the content, or why it could not be read in bounds. */
|
|
439
|
-
type BoundedFileRead = {
|
|
440
|
-
readonly kind: "ok";
|
|
441
|
-
readonly content: string;
|
|
442
|
-
} | {
|
|
443
|
-
readonly kind: "missing";
|
|
444
|
-
} | {
|
|
445
|
-
readonly kind: "too-large";
|
|
446
|
-
};
|
|
447
|
-
/** Outcome of a bounded binary read: the bytes, or why they could not be read in bounds. */
|
|
448
|
-
type BoundedBytesRead = {
|
|
449
|
-
readonly kind: "ok";
|
|
450
|
-
readonly bytes: Uint8Array;
|
|
451
|
-
} | {
|
|
452
|
-
readonly kind: "missing";
|
|
453
|
-
} | {
|
|
454
|
-
readonly kind: "too-large";
|
|
455
|
-
};
|
|
456
|
-
/**
|
|
457
|
-
* The minimal file-system surface the SDK needs. Reads are bounded and writes are atomic. Injectable so
|
|
458
|
-
* tests stay deterministic; the format adapters do their own file IO and bypass this seam.
|
|
459
|
-
*/
|
|
460
|
-
interface SdkFs {
|
|
461
|
-
/** Whether a readable file exists at the path. */
|
|
462
|
-
fileExists(path: string): Promise<boolean>;
|
|
463
|
-
/**
|
|
464
|
-
* Read a file as UTF-8 through a single handle, bounded to maxBytes. TOCTOU-safe: the handle is
|
|
465
|
-
* fstat'd and the read never advances past the sized length, so swapping in a larger file cannot
|
|
466
|
-
* bypass the cap. A missing or unreadable path is "missing"; a file over the cap is "too-large".
|
|
467
|
-
*/
|
|
468
|
-
readFileBounded(path: string, maxBytes: number): Promise<BoundedFileRead>;
|
|
469
|
-
/** Read a file as raw bytes with the same TOCTOU-safe, bounded discipline as {@link readFileBounded}. */
|
|
470
|
-
readBytesBounded(path: string, maxBytes: number): Promise<BoundedBytesRead>;
|
|
471
|
-
/** Write atomically: a temp file in the same directory, then rename over the target. */
|
|
472
|
-
writeFile(path: string, data: string): Promise<void>;
|
|
473
|
-
/** Write raw bytes atomically (temp file, then rename over the target). Used for the workbook. */
|
|
474
|
-
writeBytes(path: string, data: Uint8Array): Promise<void>;
|
|
475
|
-
/**
|
|
476
|
-
* Atomically create a file only if it does not already exist (O_EXCL semantics), creating any
|
|
477
|
-
* missing parent directory first. Returns true if this call created the file, false if a file
|
|
478
|
-
* was already present (no write performed). The backbone of {@link withLocaleWriteLock}'s
|
|
479
|
-
* exclusive-create lock: the parent-directory creation lives here so that primitive never touches
|
|
480
|
-
* `node:fs` directly and a fake `SdkFs` in tests never needs a real directory to exist.
|
|
481
|
-
*/
|
|
482
|
-
createExclusive(path: string, data: string): Promise<boolean>;
|
|
483
|
-
/** Delete a file if present; a no-op if it is already absent. */
|
|
484
|
-
deleteFile(path: string): Promise<void>;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
520
|
/** Where a config's resolved glossary came from: absent, inline, or a file at the recorded path. */
|
|
488
521
|
type GlossaryProvenance = {
|
|
489
522
|
readonly source: "none";
|
|
@@ -610,11 +643,18 @@ declare function loadConfig(options?: LoadConfigOptions): Promise<VerbatraConfig
|
|
|
610
643
|
* its timeout elapsed, because another process is holding it (or an orphaned lock file was left
|
|
611
644
|
* behind by a killed process); the message names the lock file's path (thrown by `translate`,
|
|
612
645
|
* `importWorkbook`, `editEntry`, and `retranslateEntry`).
|
|
646
|
+
* - `CONCURRENCY_INVALID`: the `concurrency` input is not an integer of at least 1 (thrown by
|
|
647
|
+
* `translate` and, per run, by `watch`, before any locale runs).
|
|
648
|
+
* - `CONCURRENCY_BUDGET_CONFLICT`: a live run requested `concurrency` greater than 1 while a token
|
|
649
|
+
* budget (`maxTokens`) is configured; the two are mutually exclusive because concurrency makes the
|
|
650
|
+
* budget's stop guarantee nondeterministic (thrown by `translate` before any provider call; a dry
|
|
651
|
+
* run is exempt, since it never folds usage into or consults the budget tracker, so the conflict
|
|
652
|
+
* cannot arise).
|
|
613
653
|
* - `LOCALE_FAILED` (NOT thrown): the fallback `code` recorded on a failed `LocaleSummary` when a
|
|
614
654
|
* per-locale failure carries no string code of its own. See the surfaced-not-thrown distinction
|
|
615
655
|
* on `translate`.
|
|
616
656
|
*/
|
|
617
|
-
type SdkErrorCode = "CONFIG_NOT_FOUND" | "CONFIG_INVALID" | "UNKNOWN_FORMAT" | "UNKNOWN_LOCALE" | "UNKNOWN_KEY" | "PROVIDER_CONSTRUCTION_FAILED" | "SOURCE_UNREADABLE" | "SOURCE_INVALID" | "LOCK_FILE_INVALID" | "LOCK_CONTENDED" | "LOCALE_FAILED";
|
|
657
|
+
type SdkErrorCode = "CONFIG_NOT_FOUND" | "CONFIG_INVALID" | "UNKNOWN_FORMAT" | "UNKNOWN_LOCALE" | "UNKNOWN_KEY" | "PROVIDER_CONSTRUCTION_FAILED" | "SOURCE_UNREADABLE" | "SOURCE_INVALID" | "LOCK_FILE_INVALID" | "LOCK_CONTENDED" | "CONCURRENCY_INVALID" | "CONCURRENCY_BUDGET_CONFLICT" | "LOCALE_FAILED";
|
|
618
658
|
/** The single structured error the SDK throws or records. Never carries a secret. */
|
|
619
659
|
declare class SdkError extends Error {
|
|
620
660
|
/** The stable {@link SdkErrorCode} for this failure; branch on this, not the message. */
|
|
@@ -635,6 +675,7 @@ declare const supportedFormatSchema: z.ZodEnum<{
|
|
|
635
675
|
xliff: "xliff";
|
|
636
676
|
yaml: "yaml";
|
|
637
677
|
arb: "arb";
|
|
678
|
+
properties: "properties";
|
|
638
679
|
}>;
|
|
639
680
|
/** One of the supported source formats; a member of {@link SUPPORTED_FORMATS}. */
|
|
640
681
|
type SupportedFormat = z.infer<typeof supportedFormatSchema>;
|
|
@@ -930,6 +971,9 @@ interface DiffDeps {
|
|
|
930
971
|
*/
|
|
931
972
|
declare function diff(input: DiffInput, deps?: DiffDeps): Promise<DiffSummary>;
|
|
932
973
|
|
|
974
|
+
/** Why {@link gateCandidateValue} rejected a candidate value. */
|
|
975
|
+
type IntegrityGateReason = "placeholder" | "icu" | "degenerate";
|
|
976
|
+
|
|
933
977
|
/** Input for {@link editEntry}: the validated config, exactly one target locale/key pair, and the human-typed replacement value. */
|
|
934
978
|
interface EditEntryInput {
|
|
935
979
|
/** The validated configuration (typically from {@link loadConfig}). */
|
|
@@ -959,7 +1003,7 @@ type EditEntryResult = {
|
|
|
959
1003
|
readonly value: string;
|
|
960
1004
|
} | {
|
|
961
1005
|
readonly accepted: false;
|
|
962
|
-
readonly reason:
|
|
1006
|
+
readonly reason: IntegrityGateReason;
|
|
963
1007
|
readonly value: string;
|
|
964
1008
|
};
|
|
965
1009
|
/**
|
|
@@ -968,7 +1012,10 @@ type EditEntryResult = {
|
|
|
968
1012
|
* locale file (merging just this one key into its current entries, every other key untouched) and
|
|
969
1013
|
* updates the lock entry for this key only (see {@link updateLockFileLocale}'s `"merge"` mode); on
|
|
970
1014
|
* rejection, writes nothing. Never calls a provider: {@link EditEntryDeps} has no provider seam,
|
|
971
|
-
* so there is no way to construct or call one.
|
|
1015
|
+
* so there is no way to construct or call one. On acceptance it also feeds the accepted value into
|
|
1016
|
+
* the local translation-memory cache (best-effort, keyed by the source content hash and the config
|
|
1017
|
+
* fingerprint), so a later run can reuse it for free; a cache failure is swallowed and never fails
|
|
1018
|
+
* the edit.
|
|
972
1019
|
*
|
|
973
1020
|
* `locale` and `key` are resolved fresh on every call, never from a cache: `locale` against
|
|
974
1021
|
* `config.targetLocales`, `key` against the source resource read fresh from disk.
|
|
@@ -1248,7 +1295,7 @@ type RetranslateEntryResult = {
|
|
|
1248
1295
|
readonly reviewReasons: readonly ReviewReasonCode[];
|
|
1249
1296
|
} | {
|
|
1250
1297
|
readonly accepted: false;
|
|
1251
|
-
readonly reason:
|
|
1298
|
+
readonly reason: IntegrityGateReason;
|
|
1252
1299
|
readonly value: string;
|
|
1253
1300
|
};
|
|
1254
1301
|
/**
|
|
@@ -1259,6 +1306,9 @@ type RetranslateEntryResult = {
|
|
|
1259
1306
|
* the lock entry for this key only (see {@link updateLockFileLocale}'s `"merge"` mode); on rejection,
|
|
1260
1307
|
* writes nothing. Reuses exactly the building blocks `translate()` already uses
|
|
1261
1308
|
* (`selectProvider`/`provider.translateBatch`) and nothing else: no bespoke per-provider plumbing.
|
|
1309
|
+
* Always calls the provider (it never consults the cache for a hit, since its whole purpose is a
|
|
1310
|
+
* fresh translation), then feeds the accepted value into the translation-memory cache best-effort so
|
|
1311
|
+
* a later run can reuse it; a cache failure is swallowed and never fails the retranslate.
|
|
1262
1312
|
*
|
|
1263
1313
|
* `locale` and `key` are resolved fresh on every call, never cached: `locale` against
|
|
1264
1314
|
* `config.targetLocales` (`UNKNOWN_LOCALE`), `key` against the source resource's own keys, read
|
|
@@ -1344,12 +1394,47 @@ interface NeedsReviewEntry {
|
|
|
1344
1394
|
/** Every {@link ReviewReasonCode} that applies to this key. */
|
|
1345
1395
|
readonly reasons: readonly ReviewReasonCode[];
|
|
1346
1396
|
}
|
|
1397
|
+
/**
|
|
1398
|
+
* One row a workbook import could not read: the 1-based worksheet row number and the header label of
|
|
1399
|
+
* the offending column. Carries no cell content, so untrusted workbook text never reaches the summary.
|
|
1400
|
+
*/
|
|
1401
|
+
interface MalformedRowReport {
|
|
1402
|
+
/** The 1-based worksheet row number of the malformed row. */
|
|
1403
|
+
readonly row: number;
|
|
1404
|
+
/** The header label of the column the row was rejected on (for example "Status"). */
|
|
1405
|
+
readonly column: string;
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* One duplicate-key conflict a workbook import found in a locale's sheet: the duplicated key and the
|
|
1409
|
+
* 1-based worksheet row number of the later (losing) occurrence. The first occurrence is the winner.
|
|
1410
|
+
*/
|
|
1411
|
+
interface DuplicateKeyReport {
|
|
1412
|
+
/** The key that appeared more than once in the locale's sheet. */
|
|
1413
|
+
readonly key: string;
|
|
1414
|
+
/** The 1-based worksheet row number of the later occurrence that lost to the first. */
|
|
1415
|
+
readonly row: number;
|
|
1416
|
+
}
|
|
1347
1417
|
/** Structured outcome for one target locale; surfaced as data on the run, never thrown. */
|
|
1348
1418
|
interface LocaleSummary {
|
|
1349
1419
|
/** The target locale this summary is for. */
|
|
1350
1420
|
readonly locale: string;
|
|
1351
|
-
/**
|
|
1352
|
-
|
|
1421
|
+
/**
|
|
1422
|
+
* This locale's honest run status (a non-success does not abort the run). `"succeeded"` when
|
|
1423
|
+
* nothing was withheld, including a genuine no-op with no candidate keys at all. `"partial"` when
|
|
1424
|
+
* at least one key was accepted and written (a {@link LocaleSummary.translated} key or a
|
|
1425
|
+
* {@link LocaleSummary.generated} plural form) but at least one was withheld (any of
|
|
1426
|
+
* {@link LocaleSummary.integrityMismatches}, {@link LocaleSummary.providerFailures}, or
|
|
1427
|
+
* {@link LocaleSummary.budgetWithheld} non-empty). `"failed"` when the locale had candidate keys
|
|
1428
|
+
* but accepted nothing at all (neither translated nor generated) while withholding at least one.
|
|
1429
|
+
* Withheld keys keep their prior lock hash and retry next run.
|
|
1430
|
+
*
|
|
1431
|
+
* A workbook import's structural findings, {@link LocaleSummary.unfilled},
|
|
1432
|
+
* {@link LocaleSummary.malformedRows}, and {@link LocaleSummary.duplicateKeys}, deliberately do NOT
|
|
1433
|
+
* feed this status: they are surfaced in their own lists (and the CLI) but are not withholdings of
|
|
1434
|
+
* an attempted translation, so a locale that dropped a malformed row, collapsed a duplicate key, or
|
|
1435
|
+
* left a `changed` row unfilled while accepting its other rows can still be `"succeeded"`.
|
|
1436
|
+
*/
|
|
1437
|
+
readonly status: "succeeded" | "partial" | "failed";
|
|
1353
1438
|
/**
|
|
1354
1439
|
* Keys translated and written this run. In dry-run, the keys that would be translated
|
|
1355
1440
|
* (the provider is not called and nothing is written).
|
|
@@ -1367,6 +1452,15 @@ interface LocaleSummary {
|
|
|
1367
1452
|
readonly pruned: readonly string[];
|
|
1368
1453
|
/** Source keys flagged invalid-ICU that were skipped for translation this run. */
|
|
1369
1454
|
readonly invalidIcuSource: readonly string[];
|
|
1455
|
+
/**
|
|
1456
|
+
* Keys served from the local translation-memory cache instead of the provider: their source content
|
|
1457
|
+
* was unchanged (possibly under a renamed key or shared with another key) and the cached value passed
|
|
1458
|
+
* the integrity gate, so no provider request was made for them. They are written and lock-advanced
|
|
1459
|
+
* exactly like a translated key, but kept distinct from {@link LocaleSummary.translated} because they
|
|
1460
|
+
* cost no provider usage. Always present, empty by default; empty in a dry-run and when the cache is
|
|
1461
|
+
* bypassed. Sorted by key.
|
|
1462
|
+
*/
|
|
1463
|
+
readonly cacheHits: readonly string[];
|
|
1370
1464
|
/**
|
|
1371
1465
|
* Translated keys that failed the placeholder-integrity check and were withheld. Never includes a
|
|
1372
1466
|
* key withheld because the provider call itself failed; see {@link LocaleSummary.providerFailures}
|
|
@@ -1419,9 +1513,34 @@ interface LocaleSummary {
|
|
|
1419
1513
|
*/
|
|
1420
1514
|
readonly needsReview: readonly NeedsReviewEntry[];
|
|
1421
1515
|
/**
|
|
1422
|
-
*
|
|
1423
|
-
*
|
|
1424
|
-
*
|
|
1516
|
+
* Keys the workbook exported as `changed` (needing an updated translation) that the translator left
|
|
1517
|
+
* blank, drifted or not, sorted by key. Pending work made visible: the row is skipped (nothing is
|
|
1518
|
+
* written and the prior lock baseline is kept), but the key is surfaced so an unfinished import is
|
|
1519
|
+
* never silently reported as done. Only a workbook import populates this; the provider path, which
|
|
1520
|
+
* never leaves a candidate key unfilled by a person, always leaves it empty.
|
|
1521
|
+
*/
|
|
1522
|
+
readonly unfilled: readonly string[];
|
|
1523
|
+
/**
|
|
1524
|
+
* Rows a workbook import could not read for this locale, each by worksheet row number and offending
|
|
1525
|
+
* column, in row order. The sheet's other rows still import; a malformed row is reported, not
|
|
1526
|
+
* written. Only a workbook import populates this; the provider path always leaves it empty.
|
|
1527
|
+
*/
|
|
1528
|
+
readonly malformedRows: readonly MalformedRowReport[];
|
|
1529
|
+
/**
|
|
1530
|
+
* Duplicate-key conflicts a workbook import found in this locale's sheet, in row order. The rule is
|
|
1531
|
+
* first occurrence wins: the first row for a key is judged and its later occurrences are reported
|
|
1532
|
+
* here and otherwise ignored. Only a workbook import populates this; the provider path always leaves
|
|
1533
|
+
* it empty.
|
|
1534
|
+
*/
|
|
1535
|
+
readonly duplicateKeys: readonly DuplicateKeyReport[];
|
|
1536
|
+
/**
|
|
1537
|
+
* A structured, secret-free error for a locale that threw (an adapter/lock/provider-construction
|
|
1538
|
+
* failure isolated as data): present only on a "failed" locale, and only that throw path sets it.
|
|
1539
|
+
* A locale that is "failed" because every candidate key was withheld (all under `providerFailures`,
|
|
1540
|
+
* `integrityMismatches`, or `budgetWithheld`) carries those lists and any notices instead, and has
|
|
1541
|
+
* no `error`. `code` is a preserved string (the underlying provider/adapter error's `code`, or
|
|
1542
|
+
* `"LOCALE_FAILED"` as a fallback), intentionally wider than {@link SdkErrorCode}, so do not treat
|
|
1543
|
+
* it as a closed set.
|
|
1425
1544
|
*/
|
|
1426
1545
|
readonly error?: {
|
|
1427
1546
|
readonly code: string;
|
|
@@ -1434,9 +1553,15 @@ interface RunSummary {
|
|
|
1434
1553
|
readonly dryRun: boolean;
|
|
1435
1554
|
/** One {@link LocaleSummary} per target locale, in config order. */
|
|
1436
1555
|
readonly locales: readonly LocaleSummary[];
|
|
1437
|
-
/** Locales whose run succeeded. */
|
|
1556
|
+
/** Locales whose run succeeded with nothing withheld (status `"succeeded"`). */
|
|
1438
1557
|
readonly succeeded: readonly string[];
|
|
1439
|
-
/**
|
|
1558
|
+
/**
|
|
1559
|
+
* Locales that wrote at least one translation but withheld at least one candidate key (status
|
|
1560
|
+
* `"partial"`). A partial locale still exits the CLI `0`: it made progress, and its withheld keys
|
|
1561
|
+
* retry next run. Never overlaps `succeeded` or `failed`.
|
|
1562
|
+
*/
|
|
1563
|
+
readonly partial: readonly string[];
|
|
1564
|
+
/** Locales whose run failed, having accepted nothing (status `"failed"`; see each locale's `error`). */
|
|
1440
1565
|
readonly failed: readonly string[];
|
|
1441
1566
|
/**
|
|
1442
1567
|
* Summed token usage across every locale's {@link LocaleSummary.usage}. Absent when no locale in the
|
|
@@ -1449,12 +1574,12 @@ interface RunSummary {
|
|
|
1449
1574
|
|
|
1450
1575
|
/**
|
|
1451
1576
|
* One target locale's snapshot inside the persisted run-status file. `status` is carried over from
|
|
1452
|
-
* `LocaleSummary.status` unchanged, so an empty `needsReview` on a failed locale is never
|
|
1453
|
-
* "this locale ran clean with nothing to review".
|
|
1577
|
+
* `LocaleSummary.status` unchanged, so an empty `needsReview` on a failed or partial locale is never
|
|
1578
|
+
* misread as "this locale ran clean with nothing to review".
|
|
1454
1579
|
*/
|
|
1455
1580
|
interface RunStatusLocale {
|
|
1456
1581
|
readonly locale: string;
|
|
1457
|
-
readonly status: "succeeded" | "failed";
|
|
1582
|
+
readonly status: "succeeded" | "partial" | "failed";
|
|
1458
1583
|
/** The full, unmodified list from `LocaleSummary.needsReview`; already bounded and content-free. */
|
|
1459
1584
|
readonly needsReview: readonly NeedsReviewEntry[];
|
|
1460
1585
|
/** Absent exactly when the source `LocaleSummary.usage` was absent; never a fabricated zero. */
|
|
@@ -1510,6 +1635,85 @@ type RunStatusResult = {
|
|
|
1510
1635
|
*/
|
|
1511
1636
|
declare function runStatus(input?: RunStatusInput, deps?: RunStatusDeps): Promise<RunStatusResult>;
|
|
1512
1637
|
|
|
1638
|
+
/** Diagnostic details, read leniently from a held lock file, about the process currently holding it. */
|
|
1639
|
+
interface LockHolder {
|
|
1640
|
+
/** The holder's process id, when the lock file could be read and carried a numeric `pid`. */
|
|
1641
|
+
readonly pid?: number;
|
|
1642
|
+
/** The holder's acquire time as an ISO-8601 string, when the lock file carried a string `acquiredAt`. */
|
|
1643
|
+
readonly acquiredAt?: string;
|
|
1644
|
+
}
|
|
1645
|
+
/** One wait-progress notification emitted while an acquire is blocked on a held lock. */
|
|
1646
|
+
interface LockWaitEvent {
|
|
1647
|
+
/** The on-disk path of the contended lock file, the exact path a person can delete if it is orphaned. */
|
|
1648
|
+
readonly lockPath: string;
|
|
1649
|
+
/** Milliseconds elapsed since this acquire started waiting, for a "still waiting" progress line. */
|
|
1650
|
+
readonly elapsedMs: number;
|
|
1651
|
+
/**
|
|
1652
|
+
* Diagnostics about the holding process, present only when the lock file could be read and parsed.
|
|
1653
|
+
* Purely for messaging; never consulted for any acquire decision.
|
|
1654
|
+
*/
|
|
1655
|
+
readonly holder?: LockHolder;
|
|
1656
|
+
}
|
|
1657
|
+
/** Called while an acquire is blocked, to surface wait progress; the lock module itself writes no output. */
|
|
1658
|
+
type LockWaitListener = (event: LockWaitEvent) => void;
|
|
1659
|
+
|
|
1660
|
+
/**
|
|
1661
|
+
* One structured progress notification emitted while a run advances through its locales and their
|
|
1662
|
+
* provider sub-batches. Emitted to a caller-supplied {@link ProgressListener}; the SDK itself writes
|
|
1663
|
+
* nothing to any stream, so a caller (the CLI) is free to render these to stderr and keep stdout a
|
|
1664
|
+
* clean summary or NDJSON stream. Discriminated on `type`, mirroring the lock-wait event contract.
|
|
1665
|
+
*/
|
|
1666
|
+
type ProgressEvent = LocaleStartedEvent | SubBatchProgressEvent | LocaleFinishedEvent | RunFinishedEvent;
|
|
1667
|
+
/** A locale is about to be processed: its position in the run's target-locale order. */
|
|
1668
|
+
interface LocaleStartedEvent {
|
|
1669
|
+
readonly type: "locale-started";
|
|
1670
|
+
/** The target locale about to run. */
|
|
1671
|
+
readonly locale: string;
|
|
1672
|
+
/** Zero-based index of this locale in the run's target-locale order. */
|
|
1673
|
+
readonly localeIndex: number;
|
|
1674
|
+
/** Total number of target locales in this run. */
|
|
1675
|
+
readonly totalLocales: number;
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* One sub-batch of a locale's main translation loop has been reached. Emitted once per loop
|
|
1679
|
+
* iteration, in order, so a caller can render a "batch N of M" line. Fired at the top of the
|
|
1680
|
+
* iteration regardless of whether the batch then makes a provider call: a budget-withheld batch
|
|
1681
|
+
* (the run's token budget already tripped) still emits this event, which keeps `batchIndex` 1-based
|
|
1682
|
+
* and contiguous against the total. A dry-run never reaches this loop and so never emits it.
|
|
1683
|
+
*/
|
|
1684
|
+
interface SubBatchProgressEvent {
|
|
1685
|
+
readonly type: "sub-batch";
|
|
1686
|
+
/** The locale whose entries this sub-batch carries. */
|
|
1687
|
+
readonly locale: string;
|
|
1688
|
+
/** One-based index of this sub-batch within the locale. */
|
|
1689
|
+
readonly batchIndex: number;
|
|
1690
|
+
/** Total number of sub-batches this locale's main translation loop runs. */
|
|
1691
|
+
readonly totalBatches: number;
|
|
1692
|
+
}
|
|
1693
|
+
/** A locale finished processing: how many keys it accepted (translated). */
|
|
1694
|
+
interface LocaleFinishedEvent {
|
|
1695
|
+
readonly type: "locale-finished";
|
|
1696
|
+
/** The target locale that finished. */
|
|
1697
|
+
readonly locale: string;
|
|
1698
|
+
/** Number of keys accepted (translated) for this locale. In a dry-run, the keys that would be translated. */
|
|
1699
|
+
readonly translated: number;
|
|
1700
|
+
}
|
|
1701
|
+
/** The run reached the end of its locale loop: how many locales it processed. */
|
|
1702
|
+
interface RunFinishedEvent {
|
|
1703
|
+
readonly type: "run-finished";
|
|
1704
|
+
/**
|
|
1705
|
+
* Number of locales the run processed (including failed locales: a per-locale failure is isolated
|
|
1706
|
+
* as a summary rather than thrown, so it is still counted here).
|
|
1707
|
+
*/
|
|
1708
|
+
readonly localesCompleted: number;
|
|
1709
|
+
}
|
|
1710
|
+
/**
|
|
1711
|
+
* Called with each {@link ProgressEvent} as a run advances; the SDK emits no output of its own. A
|
|
1712
|
+
* caller (the CLI) uses this to render progress, always to stderr, so stdout stays byte-identical to
|
|
1713
|
+
* a run with no listener attached.
|
|
1714
|
+
*/
|
|
1715
|
+
type ProgressListener = (event: ProgressEvent) => void;
|
|
1716
|
+
|
|
1513
1717
|
/** Everything the one-shot run needs: the validated config and where/how to run it. */
|
|
1514
1718
|
interface TranslateInput {
|
|
1515
1719
|
/** The validated configuration (typically from {@link loadConfig}). */
|
|
@@ -1531,6 +1735,50 @@ interface TranslateInput {
|
|
|
1531
1735
|
* unset, the config's `generatePlurals` applies.
|
|
1532
1736
|
*/
|
|
1533
1737
|
readonly generatePlurals?: boolean;
|
|
1738
|
+
/**
|
|
1739
|
+
* Called while a locale's write lock is blocked on another process holding it: once after the first
|
|
1740
|
+
* failed acquire (with the holder's pid/acquiredAt when the lock file is readable), then periodically
|
|
1741
|
+
* with the growing elapsed time. Never called for an uncontended run. The SDK writes no output; this
|
|
1742
|
+
* is the only wait-progress signal (the CLI renders its "still waiting" line from it).
|
|
1743
|
+
*/
|
|
1744
|
+
readonly onLockWait?: LockWaitListener;
|
|
1745
|
+
/**
|
|
1746
|
+
* Called as the run advances: once per locale before it starts and once after it finishes, once
|
|
1747
|
+
* per provider sub-batch within a locale, and once when the whole locale loop ends. Never fires a
|
|
1748
|
+
* sub-batch event on a dry-run (no provider call is made). The SDK writes no output; this is the
|
|
1749
|
+
* only progress signal (the CLI renders it to stderr, keeping stdout byte-identical).
|
|
1750
|
+
*
|
|
1751
|
+
* Pairing is not guaranteed when the run throws: a whole-run failure (for example a corrupt
|
|
1752
|
+
* lock-file surfacing as `LOCK_FILE_INVALID`, which re-throws instead of being isolated per locale)
|
|
1753
|
+
* can emit a `locale-started` event with no matching `locale-finished`, and no `run-finished` at
|
|
1754
|
+
* all. A per-locale failure that is isolated (not re-thrown) still emits both, and is counted in
|
|
1755
|
+
* `run-finished`.
|
|
1756
|
+
*/
|
|
1757
|
+
readonly onProgress?: ProgressListener;
|
|
1758
|
+
/**
|
|
1759
|
+
* Override how long a locale's write lock keeps retrying before failing with `LOCK_CONTENDED`, in
|
|
1760
|
+
* milliseconds. Defaults to the lock's own 10-minute default when unset (surfaced to the CLI as
|
|
1761
|
+
* `--lock-timeout`).
|
|
1762
|
+
*/
|
|
1763
|
+
readonly lockAcquireTimeoutMs?: number;
|
|
1764
|
+
/**
|
|
1765
|
+
* How many target locales may run at once, a positive integer (surfaced to the CLI as
|
|
1766
|
+
* `--concurrency`). Defaults to 1, which runs locales strictly in sequence and is byte-identical
|
|
1767
|
+
* to a run with this option unset. A value below 1 or a non-integer is rejected with a whole-run
|
|
1768
|
+
* `CONCURRENCY_INVALID` error. On a live run, a value greater than 1 is rejected with a whole-run
|
|
1769
|
+
* `CONCURRENCY_BUDGET_CONFLICT` error when the config sets a `maxTokens` budget, because
|
|
1770
|
+
* concurrency would make the budget's stop guarantee nondeterministic; a dry run is exempt. The
|
|
1771
|
+
* per-locale write locks already isolate concurrent locales on disk, so no extra locking is added.
|
|
1772
|
+
*/
|
|
1773
|
+
readonly concurrency?: number;
|
|
1774
|
+
/**
|
|
1775
|
+
* Whether to use the local content-addressed translation-memory cache (`verbatra.cache.json`). On by
|
|
1776
|
+
* default; the CLI exposes it as `--no-cache`. When false, both the cache read and the end-of-run
|
|
1777
|
+
* cache write are skipped: the run makes exactly the provider calls it would with no cache present,
|
|
1778
|
+
* and leaves any existing cache file untouched. Ignored on a dry-run, which never reads or writes the
|
|
1779
|
+
* cache regardless. See the cache module for the fingerprint and degrade-to-empty contract.
|
|
1780
|
+
*/
|
|
1781
|
+
readonly cache?: boolean;
|
|
1534
1782
|
}
|
|
1535
1783
|
/** Composition seam: inject a registry, a provider builder, and a file system for tests. */
|
|
1536
1784
|
interface TranslateDeps {
|
|
@@ -1568,7 +1816,7 @@ interface TranslateDeps {
|
|
|
1568
1816
|
*
|
|
1569
1817
|
* @param input - The validated config and run options (cwd, dryRun, prune, generatePlurals).
|
|
1570
1818
|
* @param deps - Optional composition seams (registry, provider builder, file system) for tests.
|
|
1571
|
-
* @returns A {@link RunSummary}: the per-locale {@link LocaleSummary}s and the succeeded/failed locale lists.
|
|
1819
|
+
* @returns A {@link RunSummary}: the per-locale {@link LocaleSummary}s and the succeeded/partial/failed locale lists.
|
|
1572
1820
|
* @throws {@link SdkError} `UNKNOWN_FORMAT`: no adapter is registered for the configured format.
|
|
1573
1821
|
* @throws {@link SdkError} `PROVIDER_CONSTRUCTION_FAILED`: the provider factory threw (this wraps the
|
|
1574
1822
|
* provider's own error, including a missing `*_API_KEY` reported as `MISSING_API_KEY`); only on a
|
|
@@ -1577,6 +1825,11 @@ interface TranslateDeps {
|
|
|
1577
1825
|
* @throws {@link SdkError} `SOURCE_INVALID`: the source locale file could not be read or parsed (wraps the
|
|
1578
1826
|
* adapter read error).
|
|
1579
1827
|
* @throws {@link SdkError} `LOCK_FILE_INVALID`: the lock-file is present but corrupt or oversized.
|
|
1828
|
+
* @throws {@link SdkError} `CONCURRENCY_INVALID`: `concurrency` is defined but not an integer of at
|
|
1829
|
+
* least 1; raised before any locale runs.
|
|
1830
|
+
* @throws {@link SdkError} `CONCURRENCY_BUDGET_CONFLICT`: a live run set `concurrency` greater than 1
|
|
1831
|
+
* while the config configures a `maxTokens` budget; raised before any provider call (a dry run is
|
|
1832
|
+
* exempt).
|
|
1580
1833
|
* @example
|
|
1581
1834
|
* ```ts
|
|
1582
1835
|
* import { loadConfig, translate } from "@verbatra/sdk";
|
|
@@ -1668,10 +1921,13 @@ interface ImportWorkbookDeps {
|
|
|
1668
1921
|
* identical to `translate`'s.
|
|
1669
1922
|
*
|
|
1670
1923
|
* Whole-run failures (unknown format, unreadable/invalid/oversized workbook, corrupt lock) throw a
|
|
1671
|
-
* structured {@link SdkError}. A per-sheet failure (a locale not in config, a
|
|
1672
|
-
* a write failure) is isolated as that locale's `status: "failed"`, not a
|
|
1673
|
-
* are withheld and reported on the locale.
|
|
1674
|
-
*
|
|
1924
|
+
* structured {@link SdkError}. A per-sheet failure (a sheet named for a locale not in config, a
|
|
1925
|
+
* broken-round-trip key, a write failure) is isolated as that locale's `status: "failed"`, not a
|
|
1926
|
+
* throw; per-row rejections are withheld and reported on the locale. A configured target locale with
|
|
1927
|
+
* no sheet at all (a deleted, renamed, or reordered tab) is reconciled after the sheet loop and
|
|
1928
|
+
* reported as that locale's `status: "failed"` (`WORKBOOK_SHEET_MISSING`) rather than silently
|
|
1929
|
+
* dropped. Dry-run validates and reports without writing any locale or lock file, and skips lock
|
|
1930
|
+
* acquisition (there is nothing to protect).
|
|
1675
1931
|
*
|
|
1676
1932
|
* The lock-file is read once, up front, for every sheet's diff baseline. On a non-dry-run, each
|
|
1677
1933
|
* sheet's write-and-lock-update step then holds that locale's `withLocaleWriteLock` for its whole
|
|
@@ -1750,7 +2006,7 @@ declare const scaffoldingMetadata: {
|
|
|
1750
2006
|
readonly gemini: "gemini-2.5-flash";
|
|
1751
2007
|
};
|
|
1752
2008
|
/** The closed set of source format ids. Owned by core. */
|
|
1753
|
-
readonly supportedFormats: readonly ["i18next-json", "vue-i18n-json", "next-intl-json", "ngx-translate-json", "xliff", "yaml", "arb"];
|
|
2009
|
+
readonly supportedFormats: readonly ["i18next-json", "vue-i18n-json", "next-intl-json", "ngx-translate-json", "xliff", "yaml", "arb", "properties"];
|
|
1754
2010
|
};
|
|
1755
2011
|
|
|
1756
2012
|
/** A minimal source-change event source. Production wraps chokidar; tests inject a stub. */
|
|
@@ -1789,6 +2045,30 @@ interface WatchInput {
|
|
|
1789
2045
|
readonly debounceMs?: number;
|
|
1790
2046
|
/** Called once per run with its result. The SDK does no logging; this is the only output. */
|
|
1791
2047
|
readonly onRun: (result: WatchRunResult) => void;
|
|
2048
|
+
/**
|
|
2049
|
+
* Passed through to every run's {@link TranslateInput.onLockWait}: called while a locale's write lock
|
|
2050
|
+
* is blocked on another process, so a watch caller can surface the same "still waiting" progress a
|
|
2051
|
+
* one-shot run does.
|
|
2052
|
+
*/
|
|
2053
|
+
readonly onLockWait?: LockWaitListener;
|
|
2054
|
+
/**
|
|
2055
|
+
* Passed through to every run's {@link TranslateInput.onProgress}: fires per locale and per provider
|
|
2056
|
+
* sub-batch as each run advances, so a watch caller can surface the same progress a one-shot run does.
|
|
2057
|
+
*/
|
|
2058
|
+
readonly onProgress?: ProgressListener;
|
|
2059
|
+
/** Passed through to every run's {@link TranslateInput.lockAcquireTimeoutMs}; the lock's 10-minute default when unset. */
|
|
2060
|
+
readonly lockAcquireTimeoutMs?: number;
|
|
2061
|
+
/**
|
|
2062
|
+
* Passed through to every run's {@link TranslateInput.concurrency}: how many locales each cycle may
|
|
2063
|
+
* run at once. Defaults to 1 (strictly serial). The per-cycle tracker is fresh, so a budgeted watch
|
|
2064
|
+
* with concurrency greater than 1 still fails each run with `CONCURRENCY_BUDGET_CONFLICT`.
|
|
2065
|
+
*/
|
|
2066
|
+
readonly concurrency?: number;
|
|
2067
|
+
/**
|
|
2068
|
+
* Passed through to every run's {@link TranslateInput.cache}: when false, each run bypasses the
|
|
2069
|
+
* translation-memory cache (both read and write). On by default.
|
|
2070
|
+
*/
|
|
2071
|
+
readonly cache?: boolean;
|
|
1792
2072
|
}
|
|
1793
2073
|
/** Composition seam: inject the watcher and the run for deterministic, offline tests. */
|
|
1794
2074
|
interface WatchDeps {
|
|
@@ -1845,4 +2125,4 @@ interface WatchController {
|
|
|
1845
2125
|
*/
|
|
1846
2126
|
declare function watch(input: WatchInput, deps?: WatchDeps): Promise<WatchController>;
|
|
1847
2127
|
|
|
1848
|
-
export { type BudgetBehavior, type CheckDeps, type CheckInput, type CheckSummary, type ConfigSource, type CreateProvider, type CreateWatcher, DEFAULT_WORKBOOK_PATH, type DiffDeps, type DiffInput, type DiffSummary, type EditEntryDeps, type EditEntryInput, type EditEntryResult, type ExportWorkbookDeps, type ExportWorkbookInput, type ExportWorkbookResult, type GlossaryProvenance, type ImportWorkbookDeps, type ImportWorkbookInput, type KeyIntegrityDeps, type KeyIntegrityEntry, type KeyIntegrityInput, type KeyValueDeps, type KeyValueInput, type KeyValueResult, LOCK_FILE_NAME, type LoadConfigOptions, type LoadLockFileDeps, type LoadLockFileInput, type LoadedConfig, type LocaleCheckSummary, type LocaleDiff, type LocaleFileSnapshot, type LocaleKeyIntegrity, type LocaleNotice, type LocaleSnapshotDelta, type LocaleSummary, type LockFile, type LockLocaleState, type LockStateDeps, type LockStateInput, type LockStateResult, type NeedsReviewEntry, type ProviderConfig, type ProviderId, type ReadLocaleFileSnapshotDeps, type ReadLocaleFileSnapshotInput, type RetranslateEntryDeps, type RetranslateEntryInput, type RetranslateEntryResult, type ReviewReasonCode, type RunBudget, type RunStatusDeps, type RunStatusFile, type RunStatusInput, type RunStatusLocale, type RunStatusResult, type RunSummary, type RunTranslate, type ScaffoldableProviderId, SdkError, type SdkErrorCode, type SdkFs, type SdkNotice, type SdkNoticeCode, type SupportedFormat$1 as SupportedFormat, type TranslateDeps, type TranslateInput, type UsageSummary, type VerbatraConfig, type VerbatraConfigInput, type WatchController, type WatchDeps, type WatchInput, type WatchRunResult, type Watcher, check, defineConfig, diff, diffLocaleSnapshots, editEntry, exportWorkbook, importWorkbook, keyIntegrity, keyValue, loadConfig, loadConfigWithMeta, loadLockFile, lockState, readLocaleFileSnapshot, retranslateEntry, runStatus, scaffoldingMetadata, translate, verbatraConfigSchema, watch };
|
|
2128
|
+
export { type BudgetBehavior, CACHE_FILE_NAME, type CheckDeps, type CheckInput, type CheckSummary, type ConfigSource, type CreateProvider, type CreateWatcher, DEFAULT_WORKBOOK_PATH, type DiffDeps, type DiffInput, type DiffSummary, type DuplicateKeyReport, type EditEntryDeps, type EditEntryInput, type EditEntryResult, type ExportWorkbookDeps, type ExportWorkbookInput, type ExportWorkbookResult, type GlossaryProvenance, type ImportWorkbookDeps, type ImportWorkbookInput, type IntegrityGateReason, type KeyIntegrityDeps, type KeyIntegrityEntry, type KeyIntegrityInput, type KeyValueDeps, type KeyValueInput, type KeyValueResult, LOCK_FILE_NAME, type LoadConfigOptions, type LoadLockFileDeps, type LoadLockFileInput, type LoadedConfig, type LocaleCheckSummary, type LocaleDiff, type LocaleFileSnapshot, type LocaleFinishedEvent, type LocaleKeyIntegrity, type LocaleNotice, type LocaleSnapshotDelta, type LocaleStartedEvent, type LocaleSummary, type LockFile, type LockHolder, type LockLocaleState, type LockStateDeps, type LockStateInput, type LockStateResult, type LockWaitEvent, type LockWaitListener, type MalformedRowReport, type NeedsReviewEntry, type ProgressEvent, type ProgressListener, type ProviderConfig, type ProviderId, type ReadLocaleFileSnapshotDeps, type ReadLocaleFileSnapshotInput, type RetranslateEntryDeps, type RetranslateEntryInput, type RetranslateEntryResult, type ReviewReasonCode, type RunBudget, type RunFinishedEvent, type RunStatusDeps, type RunStatusFile, type RunStatusInput, type RunStatusLocale, type RunStatusResult, type RunSummary, type RunTranslate, type ScaffoldableProviderId, SdkError, type SdkErrorCode, type SdkFs, type SdkNotice, type SdkNoticeCode, type SubBatchProgressEvent, type SupportedFormat$1 as SupportedFormat, type TranslateDeps, type TranslateInput, type TranslationMemory, type UsageSummary, type VerbatraConfig, type VerbatraConfigInput, type WatchController, type WatchDeps, type WatchInput, type WatchRunResult, type Watcher, check, defineConfig, diff, diffLocaleSnapshots, editEntry, exportWorkbook, importWorkbook, keyIntegrity, keyValue, loadConfig, loadConfigWithMeta, loadLockFile, lockState, readLocaleFileSnapshot, retranslateEntry, runStatus, scaffoldingMetadata, translate, verbatraConfigSchema, watch };
|