Referenz / SDK
Maschinell übersetzte Seite
Übersetzungen ausführen
translate, watch und die Einstiegspunkte rund um einen Lauf, dazu Pseudolocales und typisierte Kataloge, alles aus deinen eigenen Node.js-Skripten aufrufbar.
Übersetzen und beobachten
translate
Der Einmal-Flow: die Quelle lesen, jede Ziel-Locale mit der Lock-Baseline vergleichen, die fehlenden und geänderten Keys an den Provider schicken, die Integritätsprüfungen ausführen, die Locale-Dateien schreiben und das Lock aktualisieren. Nutze ihn für Skripte, Build-Schritte und CI-Jobs.
function translate(
input: TranslateInput,
deps?: TranslateDeps,
): Promise<RunSummary>;Eigenschaft
Typ
Rückgabe: RunSummary
Wirft: UNKNOWN_, LOCALE_, UNKNOWN_, CONCURRENCY_, CONCURRENCY_, MAX_, LOCK_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, PROVIDER_, NETWORK_, CONFIG_, LOCK_, PROVENANCE_
Beispiel: Übersetzen und die Zusammenfassung lesen
Was die Tabelle nicht abdeckt:
cacheist der lokale Übersetzungsspeicher-Cache (verbatra.cache.json, ebenfalls exportiert alsCACHE_).FILE_ NAME humanEdits(ab 0.12.0): Standardmäßig bleiben veraltete Keys, die ein Mensch geschrieben, importiert oder außerhalb von verbatra geändert hat, erhalten und werden inLocaleSummary.protectedgelistet. Siehe Menschliche Übersetzungen schützen.onProgressbekommt die unten beschriebenen Fortschrittsereignisse.maxBatchSizeundbudgetBehaviorsind nur über die Konfiguration steuerbar; es gibt keine Übersteuerung pro Lauf.
Probleme des gesamten Laufs werfen einen SdkError; eine einzelne fehlschlagende Locale wirft nie,
sondern landet als status: "failed" auf dem Eintrag dieser Locale, während der Lauf weitergeht.
Siehe die Anatomie der RunSummary.
Fortschrittsereignisse Verfügbar ab 0.12.0
onProgress erhält ein ProgressEvent, eine nach type unterschiedene Union. Eine Minor-Version kann Typen ergänzen, ignoriere also einen type, den du nicht kennst.
type | Wann | Felder |
|---|---|---|
locale-started | die Arbeit an einer Locale beginnt | locale, localeIndex, totalLocales |
locale-planned | nachdem das Translation Memory befragt wurde und bevor der erste Batch gesendet wird; nur wenn ein Provider aufgerufen wird | locale, keys, batches, cacheHits |
sub-batch | direkt bevor ein Übersetzungs-Batch versucht wird | locale, batchIndex, totalBatches |
provider-retry | ein eingebauter Provider wiederholt eine Anfrage, die mit einem wiederholbaren Status fehlschlug | attempt, delayMs?, status? |
repair | ein LLM-Provider fordert die Keys erneut an, die seine erste Antwort ausgelassen hat | locale, keys |
split-retry | ein Batch, dessen Ausgabe abgeschnitten wurde, wird in zwei Hälften wiederholt | locale, keys |
batch-finished | ein Batch ist fertig, ob erfolgreich oder nicht | locale, batchIndex, totalBatches, durationMs, usage? |
writing | direkt bevor die Datei einer Locale geschrieben wird | locale |
locale-finished | die Arbeit an einer Locale endet | locale, status, translated, localeIndex, totalLocales |
run-finished | alle Locales sind fertig | localesCompleted, localesFailed |
change-detected | nur watch: eine Änderung an der Quelldatei hat sich gesetzt | paths |
idle | nur watch: ein Lauf ist fertig und keiner steht an | keine |
provider-retry nennt keine Locale, weil ein Provider den ganzen Lauf bedient. Gemini meldet die Wartezeit und den Status, Anthropic, OpenAI, OpenCode und openai-compatible melden den Versuch, sobald ihr Client ihn startet, und DeepL, Google Cloud Translation und LibreTranslate melden nichts. Ein Dry Run und eine Schätzung senden nur locale-started, locale-finished und run-finished. Die --json-Fortschrittsdatensätze der CLI bleiben bei den vier ursprünglichen Typen: locale-started, sub-batch, locale-finished und run-finished.
extract, diff mit unused und doctor mit literals nehmen ein eigenes onProgress. Es erhält ein ScanProgressEvent, { type: "files-scanned", scanned, total }, einmal nach jeder Quelldatei der Anwendung, die der Scan liest.
Eigenschaft
Typ
Eine eigene CreateProvider-Fabrik erhält ein drittes Argument, CreateProviderHooks, sobald ein Lauf Fortschritt meldet. Rufe dessen onRetry mit { attempt, delayMs?, status? } auf, dann erscheinen die Wiederholungen deines Providers als provider-retry-Ereignisse.
resolveDryRun Verfügbar ab 0.11.0
Beantwortet, ob eine Menge von Lauf-Optionen zu einem Dry Run führt. Sie nimmt dryRun und
estimate, die du gleich an translate übergibst, und liefert zurück, ob dieser Lauf einen
Provider konstruiert, eine Datei schreibt oder Geld ausgibt. Das ist die einzige Stelle, an der
entschieden wird, dass estimate ein dryRun impliziert. Greif also darauf zurück, wenn etwas rund
um einen Lauf das vorab wissen muss, statt die Implikation zu wiederholen und davon abzudriften.
function resolveDryRun(input: {
readonly dryRun?: boolean | undefined;
readonly estimate?: boolean | undefined;
}): boolean;Rückgabe: boolean
import { resolveDryRun, translate, type VerbatraConfig } from "@verbatra/sdk";
declare const config: VerbatraConfig;
const options = { dryRun: false, estimate: true };
resolveDryRun(options); // true
const summary = await translate({ config, ...options });watch
Beobachtet die Quell-Locale-Datei und führt translate bei jeder entprellten Änderung neu aus. Es
feuert beim Start sofort einen initialen Lauf, danach einen Lauf pro beruhigter Änderung. Läufe
sind serialisiert: Änderungen während eines Laufs fallen zu einem einzigen Folgelauf zusammen.
function watch(
input: WatchInput,
deps?: WatchDeps,
): Promise<WatchController>;Eigenschaft
Typ
Rückgabe: WatchController
Wirft: UNKNOWN_, LOCALE_, CONCURRENCY_, LOCK_, CONCURRENCY_, LOCALE_, LOCALE_, SOURCE_, NETWORK_, PROVIDER_, CONFIG_
Beispiel: Beobachten in einem langlaufenden Prozess
debounceMs ist standardmäßig 300. onRun wird einmal pro Lauf mit einem WatchRunResult
aufgerufen: { status: "succeeded", summary } oder
{ status: "failed", error: { code, message, causeCode?, hint? } }, wobei causeCode den Code des
Fehlers nennt, den der Fehlschlag umhüllt, und hint der nächste Schritt ist, den errorHint
liefert. onReady wird einmal aufgerufen, nachdem die Startprüfungen bestanden sind und direkt vor
dem ersten Lauf, damit du die Sitzung vor dessen Ausgabe ankündigen kannst. Wirft onReady, wird
der Watcher geschlossen, und watch lehnt mit genau diesem Fehler ab, bevor ein Lauf startet. Das
SDK loggt nichts; onRun ist die einzige Ausgabe. concurrency, cache, onProgress,
onLockWait und lockAcquireTimeoutMs werden an jeden Lauf durchgereicht und verhalten sich genau
wie bei translate. locales grenzt jeden Lauf der Sitzung auf diese Teilmenge ein und wird einmal
beim Start geprüft, nicht pro Zyklus.
Gibt einen WatchController mit einer Methode zurück, stop(), die den Watcher schließt und den
laufenden Lauf abwartet. Jeder Code aus der Zeile Wirft wird schon beim Start zurückgewiesen,
bevor der Watcher existiert, sodass watch selbst fehlschlägt, statt einen Controller
zurückzugeben. Zwei davon wiegen für eine Sitzung schwerer als für einen einzelnen Lauf: Eine
concurrency über 1 gegen eine Konfiguration, die maxTokens setzt, wirft immer
CONCURRENCY_, weil es keinen Dry-Run-Watch gibt, und ab 0.12.0 wirft ein Provider,
der sich nicht erzeugen lässt, etwa weil seine API-Key-Variable fehlt, einmal
PROVIDER_, statt jeden Lauf scheitern zu lassen. Jeder Fehlschlag nach dem
Start kommt über onRun an, und das Beobachten geht weiter.
releaseHeldLocks Verfügbar ab 0.12.0
Löscht jede Schreibsperre, die der aktuelle Prozess hält, für einen Prozess, der gleich beendet
wird, ohne seine laufenden Durchläufe abzuschließen: Die CLI ruft es auf, wenn ein Interrupt
translate oder import stoppt, und wenn ein zweiter Interrupt watch hart beendet. Die
Durchläufe, die diese Sperren genommen haben, verlieren ihren Schutz, ruf es also nur direkt vor dem
Beenden des Prozesses auf. Es nimmt keine Argumente und lehnt nur dann mit einem AggregateError
ab, der die Pfade der Sperren nennt, wenn sich eine gehaltene Sperre nicht löschen ließ, nachdem
jede Sperre versucht wurde. Eine Sperre, die ein noch laufender Vorgang währenddessen nimmt oder
nehmen will, wird mit RUN_ abgelehnt und hinterlässt keine Datei; auf eine solche
Übernahme wartet es höchstens drei Sekunden.
function releaseHeldLocks(): Promise<void>;Rückgabe: void
Eine Sperre, die trotzdem liegen bleibt, weil ein Prozess hart beendet wurde, braucht es nicht: Ein wartender Durchlauf auf derselben Maschine erkennt, dass der eingetragene Prozess nicht mehr läuft, und übernimmt die Sperre selbst. Siehe die Schreibsperre.
Pseudolokalisierung
pseudolocalize Verfügbar ab 0.11.0
Baut allein aus den Quellstrings eine künstliche Locale, sodass abgeschnittene Layouts und Strings,
die nie für die Übersetzung extrahiert wurden, auffallen, bevor überhaupt ein API-Key existiert.
Jeder Wert wird akzentuiert, um etwa ein Drittel seiner übersetzbaren Länge verlängert und in die
Begrenzungszeichen [ und ] gefasst, während Platzhalter in jeder Syntax unangetastet bleiben,
die die Adapter kennen, einschließlich ICU-Plural- und -select-Zweigen, Markup-Tags und
Escape-Sequenzen. Es konstruiert keinen Provider, liest keinen API-Key und stellt keine
Netzwerkanfrage.
function pseudolocalize(
input: PseudolocalizeInput,
deps?: PseudolocalizeDeps,
): Promise<PseudolocalizeResult>;Eigenschaft
Typ
Rückgabe: PseudolocalizeResult
Wirft: PSEUDO_, UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_, TARGET_
Beispiel: Eine Pseudo-Locale bauen
Jeder erzeugte Wert muss dasselbe Integritäts-Gate passieren wie eine Provider-Übersetzung. Ein
Wert, der das nicht schaffen würde, wird wortwörtlich aus der Quelle kopiert und in copied
genannt, statt kaputt geschrieben zu werden; der Eintrag ist also weiterhin vorhanden und wird
weiterhin gerendert.
mode wählt die Transformation aus PSEUDO_: accented, der Standard, oder bidi, das
stattdessen jedes Wort übersetzbaren Textes in eine Rechts-nach-links-Marke und -Überschreibung
fasst und Platzhalter, ICU-Syntax, Markup, Ziffern und Satzzeichen draußen lässt, ohne etwas zu
akzentuieren. Im Modus bidi ist locale standardmäßig ar-XB, ein Code, der zur Richtung rechts
nach links aufgelöst wird; wie seine arabischen Pluralregeln auf die Pluralformen deiner Quelle
treffen, steht bei verbatra pseudo.
locale ist standardmäßig en-XA und out
.verbatra-local/pseudo, was verbatra init bereits in .gitignore einträgt; das konfigurierte
files.pattern wird darin expandiert, die Datei behält also das Layout, das die Anwendung
erwartet. Eine Pseudo-Locale, die eine konfigurierte Locale benennt oder auf einer konfigurierten
Locale-Datei landen würde, wird mit PSEUDO_ zurückgewiesen, bevor irgendetwas
gelesen oder geschrieben wird; sie kann also weder eine echte Übersetzung überschreiben noch für
eine einstehen. Ebenso ein out, das absolut ist, aus cwd herausklettert oder cwd selbst
benennt, etwa ., und, wenn deps.fs realpath implementiert wie die Voreinstellung, eines,
das nach dem Auflösen symbolischer Links so landet, im Verzeichnis einer konfigurierten
Locale-Datei oder auf einer anderen Datei, von der das Projekt abhängt. Weil die Datei
außerhalb von files.pattern liegt, gibt translate nie Geld für sie aus, und check und diff
melden sie nie als abgedriftet.
Gibt ein PseudolocalizeResult zurück: die locale, den mode, den absoluten path, wie viele entries
verarbeitet wurden, wie viele transformed wurden, die copied Keys und ob überhaupt etwas
written wurde. Die Transformation ist deterministisch, ein zweiter Lauf über unveränderte Quellen
schreibt also nichts neu und meldet written als false. Bei xliff und apple-xcstrings, deren
Writer nur ein bereits vorhandenes Dokument patchen, wird die Ausgabe bei jedem Schreibvorgang neu
aus der Quelle kopiert, damit ein nach dem ersten Lauf hinzugefügter Key weiterhin in der
Pseudo-Locale ankommt; bei einer kopierten XLIFF-Datei wird target-language auf die Pseudo-Locale
umgeschrieben.
Typisierte Kataloge
generateTypes Verfügbar ab 0.11.0
Deklariert den Quellkatalog eines Projekts als TypeScript: eine Union aller Keys, die er enthält, und pro Key die Argumente, die dessen Nachricht interpoliert. Typisiere eine Übersetzungsfunktion gegen das Ergebnis, und aus einem vertippten Key oder einem fehlenden Interpolationsargument wird ein Compile-Fehler statt eines Lookup-Fehlers zur Laufzeit. Es kostet nichts: Es wird kein Provider konstruiert, keine API-Key-Umgebungsvariable gelesen und keine Netzwerkanfrage gestellt.
function generateTypes(
input: GenerateTypesInput,
deps?: GenerateTypesDeps,
): Promise<GenerateTypesResult>;Eigenschaft
Typ
Rückgabe: GenerateTypesResult
Wirft: TYPES_, TYPES_, UNKNOWN_, LOCALE_, LOCALE_, SOURCE_, SOURCE_
Beispiel: Einen typisierten Katalog erzeugen
Gelesen wird eine Datei (der Quell-Locale-Katalog), geschrieben eine Datei (die Deklaration); eine
Ziel-Locale-Datei wird nie angefasst. Die Keys sind genau das, was der Format-Adapter ohnehin schon
erzeugt hat, in Dokumentreihenfolge, zwei Läufe über einen unveränderten Katalog schreiben also
byteidentische Bytes. Die Argumente stammen aus den Platzhalter-Tokens, die der Adapter extrahiert
hat, außer in den ICU-Nachrichtenformaten (next-intl-json und arb): Dort wird jede Nachricht mit
demselben ICU-Parser gelesen, den der Adapter verwendet. Jeder Key wird als String-Literal in
Anführungszeichen ausgegeben; einer, der einen Punkt, ein reserviertes Wort, eine führende Ziffer,
ein Anführungszeichen oder gar nichts enthält, wird also wortwörtlich deklariert, statt verworfen
oder neu aufgeteilt zu werden, und ein Key, den der Adapter in excludedLeafPaths gemeldet hat,
wird überhaupt nicht deklariert.
Was nicht behauptet wird, zählt ebenso viel wie das, was deklariert wird. Eine Nachricht ohne
Platzhalter bekommt eine Form, bei der jedes übergebene Argument ein Typfehler ist; eine, deren
Platzhalter ihre Argumente benennen, bekommt eine Objektform; eine mit nummerierten oder anonymen
Platzhaltern bekommt ein readonly-Tupel. Ein ICU-Argument, das nur einige select- oder
plural-Zweige verwenden, wird als optionales Mitglied deklariert. Argumenttypen stammen
ausschließlich aus dem, was der Katalog festhält: number für ein ICU-Argument vom Typ number,
plural oder selectordinal und für einen numerischen Formatter oder eine numerische
Konvertierung, Date | number für ein ICU-Argument vom Typ date oder time und einen
i18next-Formatter datetime, string für ein ICU-Argument vom Typ select und eine
printf-String-Konvertierung, und sonst ein Alias auf string | number, nie ein großzügiges any.
Eine unescapte i18next-Interpolation ({{- name}}) wird unter dem Namen hinter ihrem Präfix
deklariert. Eine Nachricht, die der Adapter als ungültig gemeldet hat, eine, die ihre Argumente
zugleich zu benennen und zu nummerieren scheint, und eine mit einem Platzhalter-Index außerhalb des
Bereichs werden mit ihren Argumenten in unresolved deklariert, statt still als argumentlos zu
gelten. Plural-Geschwister werden nie zusammengefasst: Jedes wird für sich deklariert, und die vom
Adapter als Plural markierten werden aufgelistet.
out fällt auf
DEFAULT_ (verbatra-types.d.ts) zurück. Bevor irgendetwas gelesen oder geschrieben
wird, weist TYPES_ ein out zurück, das keine Datei benennt (auch eines, das auf
ein Pfadtrennzeichen endet), absolut ist, mit .. aus cwd herausklettert, cwd selbst benennt (.) oder nicht auf
.ts, .mts oder .cts endet, und eines, das eine konfigurierte Locale-Datei, die Lock-Datei, den
Übersetzungsspeicher-Cache, eine Datei, in der verbatra nach seiner Konfiguration sucht,
configPath, die Konfigurationsdatei, aus der config geladen wurde, oder glossaryPath benennt,
die Glossardatei, auf die sie zeigt; Namen werden ohne Rücksicht auf Groß- und Kleinschreibung
verglichen, und wenn deps.fs realpath implementiert, wie es die Voreinstellung tut, laufen
dieselben Prüfungen noch einmal auf dem Ziel, auf dem der Pfad nach dem Auflösen symbolischer Links
landet. Ein generierender Lauf weist mit demselben Code außerdem zurück, eine bestehende Datei zu
ersetzen, die nicht mit der Kopfzeile beginnt, die verbatra schreibt, und lässt diese Datei
unangetastet. Die vollständige Liste steht auf der Seite zu verbatra types. Mit
gesetztem check wird überhaupt nichts geschrieben, nichts wegen seines Inhalts zurückgewiesen, und
der Lauf meldet nur, ob die committete Datei noch passt, und genau das braucht ein CI-Gate.
Gibt ein GenerateTypesResult zurück: den absoluten path, den sourcePath, aus dem es gebaut
wurde, wie viele keys deklariert wurden und wie viele davon mindestens ein Argument nehmen, das
verbatra bestimmen konnte (withArguments, das einen Key aus unresolved nie mitzählt), die
unresolved Keys sowie die excluded und plural Keys, ob etwas written wurde, ob die Datei auf
der Platte beim Start stale war, ob sie ganz fehlte (missing, eine fehlende Datei ist auch
stale) und ob dies ein check-Lauf war.