Recetas del SDK
Patrones completos y ejecutables para manejar verbatra desde tus propios scripts, jobs de CI y herramientas.
Página traducida automáticamente
La referencia del SDK cataloga cada punto de entrada. Esta página es la compañera práctica:
recetas de principio a fin que puedes copiar en un script y ejecutar. Una cosa que preparar primero: el
SDK no carga archivos .env (eso lo hace la CLI), así que asegúrate de que la variable de entorno del
proveedor está definida antes de que corra tu script, por ejemplo:
node --env-file=.env translate.mjsTraducción única en un script
Carga la configuración, ejecuta el flujo y luego lee el resumen: el titular en succeeded y failed,
el gasto de tokens en usage y las claves que merecen una mirada humana en el needsReview de cada
locale. Los problemas de toda la ejecución lanzan un SdkError; los resultados por locale son datos en
el resumen.
import { loadConfig, translate } from "@verbatra/sdk";
const config = await loadConfig();
const summary = await translate({ config });
console.log(`${summary.succeeded.length} locales ok, ${summary.failed.length} failed`);
if (summary.usage !== undefined) {
console.log(`tokens: ${summary.usage.inputTokens} in, ${summary.usage.outputTokens} out`);
}
for (const locale of summary.locales) {
if (locale.status === "failed") {
console.error(`${locale.locale}: ${locale.error?.code} ${locale.error?.message}`);
continue;
}
for (const entry of locale.needsReview) {
console.warn(`review ${locale.locale}/${entry.key}: ${entry.reasons.join(", ")}`);
}
}
if (summary.failed.length > 0) {
process.exitCode = 1;
}Pasa dryRun: true para previsualizar sin llamar a un proveedor ni escribir nada, y prune: true o
generatePlurals: true para anular esas opciones de configuración durante una ejecución. Pon
concurrency por encima de 1 para traducir locales en paralelo (no permitido con un presupuesto
maxTokens en una ejecución real) y cache: false para omitir la
caché de memoria de traducción.
Comprueba en CI sin escribir
check lee y compara sin llamar a un proveedor ni tocar ningún archivo, y su indicador inSync es true
exactamente cuando no hay nada faltante ni obsoleto. Eso lo convierte en la puerta natural de CI.
import { check, loadConfig } from "@verbatra/sdk";
const summary = await check({ config: await loadConfig() });
if (!summary.inSync) {
for (const locale of summary.locales) {
if (!locale.inSync) {
console.error(`${locale.locale}: ${locale.missing} missing, ${locale.stale} stale`);
}
}
process.exitCode = 1;
}¿Necesitas los nombres de las claves en lugar de contadores? Cambia a diff, que devuelve listas de
claves missing, changed y orphaned por locale con la misma puerta hasPendingChanges. ¿Ejecutas
la CLI en CI en su lugar? Consulta CI y códigos de salida.
Vigila en un proceso de larga duración
watch dispara una ejecución inmediatamente al arrancar, y luego una por cada cambio del origen
asentado por el anti-rebote, informando de cada una a través de onRun. Para un apagado limpio, espera
controller.stop() con await: cierra el watcher y espera a que termine la ejecución en curso antes de
que salga tu proceso.
import { loadConfig, watch } from "@verbatra/sdk";
const config = await loadConfig();
const controller = await watch({
config,
onRun: (result) => {
if (result.status === "succeeded") {
console.log(`ran: ${result.summary.succeeded.length} ok, ${result.summary.failed.length} failed`);
} else {
console.error(`run failed: ${result.error.code} ${result.error.message}`);
}
},
});
process.on("SIGINT", () => {
void controller.stop().then(() => {
process.exit(0);
});
});Un fallo de ejecución después del arranque nunca lanza; llega como { status: "failed" } y la
vigilancia continúa.
Edita y retraduce una sola clave
Estos son los puntos de integración que usa Verbatra Studio; úsalos para construir tu propio flujo de
revisión. Lee los valores actuales con keyValue, guarda una corrección humana con editEntry o vuelve
a ejecutar el proveedor para una clave con retranslateEntry. Ambos escritores pasan el valor candidato
por las mismas comprobaciones de marcadores de posición e ICU que una ejecución completa y devuelven un
resultado de dos ramas en lugar de lanzar ante un valor rechazado.
import { editEntry, keyValue, loadConfig, retranslateEntry } from "@verbatra/sdk";
const config = await loadConfig();
// Read the live values feeding your edit UI.
const current = await keyValue({ config, locale: "de", key: "checkout.title" });
console.log(`source: ${current.source}, target: ${current.target ?? "(not yet translated)"}`);
// Save a human-typed correction. No provider call.
const edit = await editEntry({
config,
locale: "de",
key: "checkout.title",
value: "Zur Kasse",
});
if (!edit.accepted) {
console.error(`rejected (${edit.reason} check failed), nothing written`);
}
// Or ask the provider for a fresh translation of just this key.
const retry = await retranslateEntry({ config, locale: "de", key: "checkout.title" });
if (retry.accepted) {
console.log(`wrote: ${retry.value}`);
if (retry.reviewReasons.length > 0) {
console.warn(`flagged for review: ${retry.reviewReasons.join(", ")}`);
}
}Un locale o una clave desconocidos lanzan UNKNOWN_LOCALE o UNKNOWN_KEY, y retranslateEntry lanza
el ProviderError propio del proveedor (por ejemplo RATE_LIMITED) cuando la llamada en sí falla.
Consulta Revisión en Studio para los mismos puntos de integración detrás de
una interfaz.
El ciclo de ida y vuelta del libro
Exporta las cadenas que necesitan traducción a un libro de Excel, entrégaselo a un traductor y luego
importa el archivo rellenado de vuelta. importWorkbook ejecuta las mismas comprobaciones de desfase,
marcadores de posición e ICU que translate y devuelve la misma forma RunSummary, así que una entrega
manual encaja en el mismo informe exacto que usas para una ejecución automática.
import { exportWorkbook, importWorkbook, loadConfig } from "@verbatra/sdk";
const config = await loadConfig();
// Write a workbook of the missing and changed strings.
const exported = await exportWorkbook({ config });
for (const sheet of exported.locales) {
console.log(`${sheet.locale}: ${sheet.rows} rows`);
}
console.log(`wrote ${exported.path}`);
// ...later, after the translator returns the file, import it back.
const summary = await importWorkbook({ config, workbook: exported.path });
console.log(`${summary.succeeded.length} locales ok, ${summary.failed.length} failed`);Pasa dryRun: true a importWorkbook para validar un archivo devuelto sin escribir nada. Consulta
Traducción humana para saber qué pueden editar los traductores y cómo se
validan las filas.
Una configuración sin archivo
loadConfig acepta un configOverride en memoria, validado exactamente igual que un archivo cargado,
así que puedes manejar verbatra enteramente desde código sin ningún archivo de configuración en disco.
import { loadConfig, translate } from "@verbatra/sdk";
const config = await loadConfig({
configOverride: {
sourceLocale: "en",
targetLocales: ["de", "fr"],
format: "i18next-json",
files: { pattern: "locales/{locale}.json" },
provider: { id: "gemini", options: { model: "gemini-2.5-flash", maxOutputTokens: 4096 } },
},
});
await translate({ config });Para cada forma de entrada, la anatomía completa de RunSummary y la tabla de códigos de SdkError,
consulta la referencia del SDK.