Zum Inhalt springen

Referenz / SDK

Maschinell übersetzte Seite

Diese Seite wurde automatisch übersetzt und kann daher Fehler oder seltsame Formulierungen enthalten. Die englische Version ist die maßgebliche Quelle. Das englische Original lesen.

Ü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.

Signatur
function translate(
  input: TranslateInput,
  deps?: TranslateDeps,
): Promise<RunSummary>;

Eigenschaft

Typ

Rückgabe: RunSummary

Wirft: UNKNOWN_LOCALE, LOCALE_UNSUPPORTED_BY_PROVIDER, UNKNOWN_FORMAT, CONCURRENCY_INVALID, CONCURRENCY_BUDGET_CONFLICT, MAX_TOKENS_INVALID, LOCK_TIMEOUT_INVALID, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, PROVIDER_CONSTRUCTION_FAILED, NETWORK_POLICY_VIOLATION, CONFIG_INVALID, LOCK_FILE_INVALID, PROVENANCE_FILE_INVALID

Beispiel: Übersetzen und die Zusammenfassung lesen

Was die Tabelle nicht abdeckt:

  • cache ist der lokale Übersetzungsspeicher-Cache (verbatra.cache.json, ebenfalls exportiert als CACHE_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 in LocaleSummary.protected gelistet. Siehe Menschliche Übersetzungen schützen.
  • onProgress bekommt die unten beschriebenen Fortschrittsereignisse.
  • maxBatchSize und budgetBehavior sind 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.

typeWannFelder
locale-starteddie Arbeit an einer Locale beginntlocale, localeIndex, totalLocales
locale-plannednachdem das Translation Memory befragt wurde und bevor der erste Batch gesendet wird; nur wenn ein Provider aufgerufen wirdlocale, keys, batches, cacheHits
sub-batchdirekt bevor ein Übersetzungs-Batch versucht wirdlocale, batchIndex, totalBatches
provider-retryein eingebauter Provider wiederholt eine Anfrage, die mit einem wiederholbaren Status fehlschlugattempt, delayMs?, status?
repairein LLM-Provider fordert die Keys erneut an, die seine erste Antwort ausgelassen hatlocale, keys
split-retryein Batch, dessen Ausgabe abgeschnitten wurde, wird in zwei Hälften wiederholtlocale, keys
batch-finishedein Batch ist fertig, ob erfolgreich oder nichtlocale, batchIndex, totalBatches, durationMs, usage?
writingdirekt bevor die Datei einer Locale geschrieben wirdlocale
locale-finisheddie Arbeit an einer Locale endetlocale, status, translated, localeIndex, totalLocales
run-finishedalle Locales sind fertiglocalesCompleted, localesFailed
change-detectednur watch: eine Änderung an der Quelldatei hat sich gesetztpaths
idlenur watch: ein Lauf ist fertig und keiner steht ankeine

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.

Signatur
function resolveDryRun(input: {
  readonly dryRun?: boolean | undefined;
  readonly estimate?: boolean | undefined;
}): boolean;

Rückgabe: boolean

Beispiel
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.

Signatur
function watch(
  input: WatchInput,
  deps?: WatchDeps,
): Promise<WatchController>;

Eigenschaft

Typ

Rückgabe: WatchController

Wirft: UNKNOWN_LOCALE, LOCALE_UNSUPPORTED_BY_PROVIDER, CONCURRENCY_INVALID, LOCK_TIMEOUT_INVALID, CONCURRENCY_BUDGET_CONFLICT, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, NETWORK_POLICY_VIOLATION, PROVIDER_CONSTRUCTION_FAILED, CONFIG_INVALID

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_BUDGET_CONFLICT, 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_CONSTRUCTION_FAILED, 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_CANCELLED abgelehnt und hinterlässt keine Datei; auf eine solche Übernahme wartet es höchstens drei Sekunden.

Signatur
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.

Signatur
function pseudolocalize(
  input: PseudolocalizeInput,
  deps?: PseudolocalizeDeps,
): Promise<PseudolocalizeResult>;

Eigenschaft

Typ

Rückgabe: PseudolocalizeResult

Wirft: PSEUDO_OUTPUT_CONFLICT, UNKNOWN_FORMAT, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID, TARGET_UNWRITABLE

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.

Verfügbar ab 0.12.0

mode wählt die Transformation aus PSEUDO_MODES: 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_OUTPUT_CONFLICT 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.

Signatur
function generateTypes(
  input: GenerateTypesInput,
  deps?: GenerateTypesDeps,
): Promise<GenerateTypesResult>;

Eigenschaft

Typ

Rückgabe: GenerateTypesResult

Wirft: TYPES_OUTPUT_CONFLICT, TYPES_UNWRITABLE, UNKNOWN_FORMAT, LOCALE_LAYOUT_INVALID, LOCALE_PATH_COLLISION, SOURCE_UNREADABLE, SOURCE_INVALID

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_TYPES_PATH (verbatra-types.d.ts) zurück. Bevor irgendetwas gelesen oder geschrieben wird, weist TYPES_OUTPUT_CONFLICT 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.

Auf GitHub bearbeiten

Auf dieser Seite