Referencia del SDK
Cada punto de entrada de @verbatra/sdk, agrupado por tarea, con el modelo de errores y la anatomía de RunSummary.
Página traducida automáticamente
@verbatra/sdk es el motor sobre el que corre el comando verbatra. La CLI es una envoltura fina, así que todo
lo que hace la línea de comandos lo puedes hacer en código. Esta página cataloga toda la superficie pública,
agrupada por la tarea que hace cada punto de entrada. Para ejemplos de principio a fin, consulta
Recetas del SDK.
Instalación
pnpm add -D @verbatra/sdk
# npm
npm install -D @verbatra/sdk
# yarn
yarn add -D @verbatra/sdkRequiere Node.js >=22.14.0.
Las claves API y el entorno
El SDK nunca lee, guarda ni acepta una clave API. El proveedor lee su clave del entorno
(por ejemplo ANTHROPIC_API_KEY) cuando se construye. A diferencia de la CLI, el SDK no carga
archivos .env: en tu propio script, define tú la variable, por ejemplo con
node --env-file=.env script.js.
Cada punto de entrada toma un objeto de entrada cuyo primer campo es la config validada (de
loadConfig), salvo donde se indica. La mayoría también acepta un segundo argumento opcional deps que
inyecta un registro, un constructor de proveedor o un sistema de archivos para pruebas; puedes ignorarlo
en el uso normal.
Ejecuta traducciones
translate
El flujo de una sola pasada: leer el origen, comparar cada locale de destino con la línea base del bloqueo, enviar al proveedor las claves faltantes y modificadas, ejecutar las comprobaciones de integridad de marcadores de posición e ICU, escribir los archivos de locale y actualizar el bloqueo. Úsalo para scripts, pasos de build y jobs de CI.
Entrada: { config, cwd?, dryRun?, prune?, generatePlurals?, concurrency?, cache?, onProgress?, onLockWait?, lockAcquireTimeoutMs? }.
dryRunlee, compara e informa sin construir ni llamar al proveedor y sin escribir nada.pruneelimina del archivo escrito y del bloqueo las claves huérfanas (claves de destino ausentes del origen).generatePluralssintetiza las formas de plural CLDR que faltan (solo i18next-JSON con un proveedor LLM). Ambos están desactivados por defecto; cuando se definen, cada uno anula la opción de configuración correspondiente para esa ejecución.concurrencytraduce hasta ese número de locales de destino a la vez (por defecto 1, estrictamente en serie). Un valor menor que 1 lanzaCONCURRENCY_INVALID; en una ejecución real, un valor mayor que 1 conmaxTokensconfigurado lanzaCONCURRENCY_BUDGET_CONFLICT(un dry-run queda exento).cacheestá activado por defecto y reutiliza la caché de memoria de traducción local; ponlo en false para omitir la caché en la ejecución (el--no-cachede la CLI).onProgressse llama a medida que avanza la ejecución (por inicio y fin de cada locale, y por sub-lote del proveedor), yonLockWaitse dispara mientras el bloqueo de escritura de un locale está en disputa. Ambos son callbacks de notificación; el SDK no escribe nada por sí mismo.lockAcquireTimeoutMsanula cuánto tiempo reintenta un bloqueo de escritura en disputa antes de fallar conLOCK_CONTENDED.maxBatchSize,maxTokensybudgetBehaviorson solo de configuración; no hay anulación por ejecución.
Devuelve un RunSummary (consulta su anatomía más abajo). Los problemas
de toda la ejecución lanzan un SdkError; que falle un solo locale nunca lanza y queda como
status: "failed" en la entrada de ese locale mientras la ejecución continúa.
watch
Vigila el archivo del locale de origen y vuelve a ejecutar translate en cada cambio asentado por el
anti-rebote. Dispara una ejecución inicial inmediatamente al arrancar, y luego una ejecución por cambio
asentado. Las ejecuciones se serializan: los cambios durante una ejecución se colapsan en un único
seguimiento.
Entrada: { config, cwd?, debounceMs?, onRun, concurrency?, cache?, onProgress?, onLockWait?, lockAcquireTimeoutMs? }.
debounceMs es 300 por defecto. onRun se llama una vez por ejecución con un WatchRunResult:
{ status: "succeeded", summary } o { status: "failed", error: { code, message } }. El SDK no
registra nada; onRun es la única salida. concurrency, cache, onProgress, onLockWait y
lockAcquireTimeoutMs se pasan a cada ejecución y se comportan igual que en translate (un watch con
presupuesto y concurrency mayor que 1 falla en cada ejecución con CONCURRENCY_BUDGET_CONFLICT).
Devuelve un WatchController con un solo método, stop(), que cierra el watcher y espera la ejecución
en curso. Un archivo de origen ausente lanza SOURCE_UNREADABLE al arrancar; todo fallo posterior se
comunica a través de onRun y la vigilancia continúa.
Inspecciona el estado sin escribir
Ninguna de estas llama a un proveedor, escribe un archivo ni muta el bloqueo.
check
Informa del desfase por locale como contadores: missing (en el origen, ausente del destino), stale
(el origen cambió desde la última traducción) y upToDate. Úsalo como puerta de CI.
Entrada: { config, cwd?, locales? }. Devuelve un CheckSummary cuyo inSync es true exactamente
cuando cada locale comprobado no tiene nada faltante ni obsoleto.
diff
El hermano detallado de check: el mismo cálculo, pero devuelve las listas de claves por locale
(missing, changed, orphaned) en lugar de contadores. Las claves huérfanas son solo informativas y
nunca activan hasPendingChanges, porque una ejecución por defecto no elimina claves.
Entrada: { config, cwd?, locales? }. Devuelve un DiffSummary.
keyIntegrity
Informa, para las claves modificadas de cada locale, de si el valor de destino actual sigue coincidiendo
con los marcadores de posición del origen y de si es ICU válido. Cada entrada lleva key,
hasPlaceholders, matches, los tokens de marcador missing y extra en una discrepancia, e
icuValid. Las entradas nunca llevan un valor de cadena de origen o destino. Este es el informe de
integridad por clave que muestra Studio.
Entrada: { config, cwd?, locales?, keys? }. keys acota la comprobación; solo se comprueban las
claves que están "modificadas" para un locale. Devuelve un LocaleKeyIntegrity por locale comprobado.
lockState
Informa de la existencia del archivo de bloqueo, su versión y el desfase por locale (número de claves de
la línea base más contadores de faltantes, obsoletas y al día). exists viene de una sonda explícita,
así que "todavía no hay archivo de bloqueo" y "un archivo de bloqueo vacío pero presente" siguen siendo
distinguibles. Cuando el archivo está ausente el resultado es { exists: false } y no se lee nada más.
Entrada: { config, cwd?, locales? }. Devuelve un LockStateResult.
loadLockFile
Lee el propio archivo de bloqueo (verbatra.lock.json, exportado también como LOCK_FILE_NAME) y
devuelve su forma parseada: { version, locales }, donde cada locale asigna claves al hash del
contenido de origen desde el que se tradujeron por última vez. Un archivo ausente degrada a un bloqueo
vacío, el mismo comportamiento de primera ejecución en el que se apoya translate; usa lockState
cuando necesites distinguir la ausencia.
Entrada: { cwd? }. No necesita configuración. Devuelve un LockFile.
runStatus
Lee la instantánea de señales de revisión y uso de tokens que la ejecución más reciente de translate o
watch (no en seco) persistió en .verbatra-local/run-status.json. Nunca lanza: un archivo ausente,
corrupto o no reconocido degrada a { available: false }. Este archivo es telemetría de mejor esfuerzo,
no una línea base de corrección.
Entrada: { cwd? }. No necesita configuración. Devuelve { available: false } o
{ available: true, version, generatedAt, usage?, budget?, locales }.
Operaciones de una sola clave
Estos son los puntos de integración que usa Verbatra Studio; úsalos para construir tu propia herramienta
de revisión. Los tres resuelven locale y key de nuevo en cada llamada y lanzan UNKNOWN_LOCALE o
UNKNOWN_KEY cuando alguno no existe.
keyValue
Lee el valor de origen actual de una clave y, cuando existe, su valor de destino actual para un locale. Solo lectura.
Entrada: { config, cwd?, locale, key }. Devuelve { source, target? }; target está ausente
exactamente cuando la clave todavía no existe en ese locale.
editEntry
Escribe una corrección tecleada por un humano para una clave y un locale. El valor candidato pasa por la misma puerta de marcadores de posición e ICU que una traducción del proveedor antes de que nada llegue al disco; al aceptarse, el archivo de locale y la entrada del bloqueo de esa clave se actualizan dentro del bloqueo de escritura del locale. Nunca llama a un proveedor.
Entrada: { config, cwd?, locale, key, value }. Devuelve un resultado de dos ramas:
{ accepted: true, value }, o { accepted: false, reason: "placeholder" | "icu", value } sin escribir
nada.
retranslateEntry
Vuelve a ejecutar el proveedor para exactamente una clave y un locale: una llamada de una sola entrada a
través del mismo registro de proveedores que usa translate, protegida por las mismas comprobaciones de
integridad. Al aceptarse escribe el archivo de locale y la entrada del bloqueo solo para esa clave.
Entrada: { config, cwd?, locale, key }. Devuelve { accepted: true, value, reviewReasons } (los
códigos de motivo de revisión, si los hay, que aplican al nuevo valor) o
{ accepted: false, reason: "placeholder" | "icu", value }. A diferencia de translate, aquí un fallo
del proveedor lanza: un ProviderError de @verbatra/ai-providers con un código estable como
RATE_LIMITED o AUTH_FAILED.
Instantáneas de archivos de locale
Los bloques con los que se construye un vigilante de actualización en vivo como el de Studio: captura el estado de un archivo de locale y luego cuenta qué cambió desde entonces.
readLocaleFileSnapshot
Lee un archivo de locale (el locale de origen o cualquier locale de destino) y lo reduce a un hash de contenido por clave. Un archivo que todavía no existe se lee como una instantánea vacía en lugar de lanzar.
Entrada: { config, locale, cwd? }. Devuelve { locale, hashes }.
diffLocaleSnapshots
Compara dos instantáneas del mismo archivo, tomadas en momentos distintos, y cuenta las claves añadidas,
modificadas y eliminadas entre ambas. Una función síncrona normal: diffLocaleSnapshots(previous, current) devuelve { added, changed, removed }. Solo contadores, nunca nombres de claves.
El par de libro
La entrega en Excel para traductores humanos; consulta Traducción humana.
exportWorkbook
Escribe las cadenas que todavía necesitan traducción (claves faltantes y modificadas por locale; añade
las sin cambios con includeUnchanged) en un libro .xlsx con estilos. Las filas llevan la misma señal
de revisión que calcula una ejecución de translate. Sin llamada al proveedor, sin escritura del bloqueo.
Entrada: { config, cwd?, out?, locales?, includeUnchanged? }. out es por defecto
DEFAULT_WORKBOOK_PATH (verbatra-translations.xlsx), exportado como constante. Devuelve
{ path, locales }: la ruta absoluta escrita y un número de filas por locale.
importWorkbook
Lee un libro rellenado de vuelta a los archivos de locale, ejecutando las mismas comprobaciones de
desfase del origen, marcadores de posición e ICU que translate. Solo las filas aceptadas avanzan su
línea base del bloqueo; una fila en blanco o rechazada se sigue exportando hasta que se resuelve de
verdad.
Entrada: { config, workbook, cwd?, dryRun? }. Devuelve la misma forma RunSummary que translate
(con needsReview siempre vacío, ya que no interviene ningún proveedor). Una hoja de un locale que no
es un destino configurado hace fallar ese locale con CONFIG_INVALID como dato en el resumen, no como
excepción.
Configuración
loadConfig
Encuentra, carga y valida la configuración del proyecto, devolviendo una VerbatraConfig. Opciones:
{ cwd?, configPath?, configOverride? }, con precedencia de configOverride (validar un objeto en
memoria) sobre configPath (cargar un archivo explícito) sobre la búsqueda. La búsqueda empieza en
cwd y cubre verbatra.config.ts (también .js/.cjs), la familia .verbatrarc (.json, .yaml,
.yml, .js, .cjs, .ts) y una propiedad "verbatra" en package.json. Un glossary dado como
ruta de archivo se lee y valida aquí, así que el código posterior siempre ve un registro plano.
Lanza CONFIG_NOT_FOUND cuando no se encuentra nada, CONFIG_INVALID cuando se encuentra una
configuración pero es inválida. Consulta Archivo de configuración para el esquema.
loadConfigWithMeta
La misma carga, más la procedencia: devuelve { config, source, glossary }, donde source dice si la
configuración vino de un acierto de búsqueda, de una ruta explícita o de una anulación en memoria (con
el filepath absoluto cuando lo hay), y glossary registra si el glosario estaba ausente, en línea o
resuelto desde un archivo. Úsalo cuando necesites mostrar de dónde salió la configuración.
defineConfig
Un ayudante identidad para escribir un verbatra.config.ts tipado: devuelve su argumento sin cambios y
existe puramente para la inferencia de tipos y el autocompletado del editor, incluido el completado de
los IDs de modelo conocidos del proveedor seleccionado. La restricción de modelos es solo al escribir;
en tiempo de ejecución cualquier cadena no vacía pasa la validación.
verbatraConfigSchema
El esquema zod con el que valida loadConfig, exportado para que tu propia herramienta pueda validar un
objeto de configuración igual que lo hace el SDK. Las claves desconocidas de nivel superior se rechazan,
así que un secreto extraviado no puede esconderse en la configuración.
scaffoldingMetadata
Metadatos de solo lectura de los que el comando init de la CLI deriva sus preguntas: providerEnv (de
id de proveedor a la variable de entorno de la que se lee su clave), scaffoldModels (un modelo de
scaffold por defecto por proveedor LLM) y supportedFormats (el conjunto cerrado de ids de formato). El
tipo ScaffoldableProviderId cubre los cuatro proveedores alojados; openai-compatible queda excluido
porque no tiene una única variable de entorno obligatoria.
La anatomía de RunSummary
translate, importWorkbook y cada ejecución exitosa de watch resuelven a un RunSummary:
interface RunSummary {
dryRun: boolean; // true when nothing was written and no provider was called
locales: LocaleSummary[]; // one entry per target locale, in config order
succeeded: string[]; // locales whose run succeeded
failed: string[]; // locales whose run failed
usage?: UsageSummary; // summed input/output tokens; absent when no call reported usage
budget?: RunBudget; // present only when maxTokens is configured
}
interface LocaleSummary {
locale: string;
status: "succeeded" | "failed";
translated: string[]; // keys translated this run (in dry-run, keys that would be)
cacheHits: string[]; // keys served from the translation-memory cache this run
unchanged: string[]; // keys already up to date
orphaned: string[]; // target keys with no matching source key (always reported)
pruned: string[]; // orphaned keys removed this run; empty unless pruning is on
invalidIcuSource: string[]; // source keys skipped for invalid ICU
integrityMismatches: string[]; // translations withheld for a placeholder mismatch
providerFailures: string[]; // keys withheld because nothing was translated for them
budgetWithheld: string[]; // keys never sent because a "stop" budget already tripped
generated: string[]; // CLDR plural forms synthesized this run
unfilled: string[]; // import only: changed rows the translator left blank
malformedRows: { row: number; column: string }[]; // import only: rows the reader could not parse
duplicateKeys: { key: string; row: number }[]; // import only: later rows for a duplicated key
notices: LocaleNotice[]; // provider notices and SDK notices for this locale
needsReview: { key: string; reasons: string[] }[]; // accepted keys flagged for a second look
usage?: UsageSummary; // this locale's summed tokens; absent if nothing reported usage
error?: { code: string; message: string }; // present only when status is "failed"
}Las partes que conviene conocer:
- needsReview lista claves aceptadas y escritas que las heurísticas de revisión marcaron, cada una
con sus códigos de motivo:
LENGTH_RATIO_OUTLIER,EQUALS_SOURCE,GLOSSARY_TERM_MISSED,INTEGRITY_REORDEREDyPROVIDER_DEGRADED. Una señal de revisión es consultiva y nunca retiene una clave, así que una clave nunca aparece a la vez enneedsReviewy enintegrityMismatches. Consulta Seguridad de la traducción para saber qué significa cada código y Revisión en Studio para trabajar la cola. - notices vive por locale, nunca en el nivel superior. Cubre avisos del proveedor (por ejemplo, una
degradación de DeepL) y avisos del SDK con los códigos
PLURAL_CATEGORIES_INCOMPLETE,SUB_BATCH_FAILED,BLANK_ROW_BASELINE_RETAINEDyBUDGET_TOKENS_EXCEEDED. - usage es
undefined, nunca un cero inventado, siempre que nada en ese ámbito informara de uso: una ejecución en seco nunca llama a un proveedor, y DeepL nunca informa de tokens.RunSummary.usagees la suma sobre los locales. - budget aparece solo cuando
maxTokensestá configurado:{ maxTokens, behavior, supported, tokensUsed, exceeded }. Frente a un proveedor sin tokens o una ejecución en seco sigue presente consupported: false, así que la barrera es visiblemente inerte en lugar de dispararse en falso. - error.code en un locale fallido es una cadena preservada (el código subyacente del proveedor o del
adaptador, con
LOCALE_FAILEDsolo como reserva), así que no lo trates como un conjunto cerrado. - cacheHits lista las claves servidas desde la caché de memoria de traducción
en lugar del proveedor. unfilled, malformedRows y duplicateKeys solo los rellena
importWorkbook(una ejecución detranslatelos deja vacíos): una filachangeden blanco, una fila del libro que el lector no pudo parsear y una clave duplicada cuya primera aparición ganó.
El modelo de errores
Los fallos de toda la ejecución lanzan un SdkError: una sola clase, un code estable y un message
sin secretos. Ramifica sobre el código, no sobre el mensaje. Los fallos por locale, los avisos del
proveedor y los hallazgos de integridad se comunican como datos en el RunSummary, nunca se lanzan.
| Código | Cuándo |
|---|---|
CONFIG_NOT_FOUND | la búsqueda no encontró ninguna configuración, o un configPath explícito no existe (lanzado por loadConfig) |
CONFIG_INVALID | se encontró una configuración pero no se puede parsear o falla la validación, o su archivo de glosario no se pudo resolver |
UNKNOWN_FORMAT | no hay adaptador registrado para el formato configurado; se lanza antes de leer ningún archivo |
UNKNOWN_LOCALE | un locale solicitado no está entre los locales de destino configurados |
UNKNOWN_KEY | una clave solicitada no está en el recurso de origen (keyValue, editEntry, retranslateEntry) |
PROVIDER_CONSTRUCTION_FAILED | el proveedor no se pudo construir; envuelve el error propio del proveedor, incluida una clave API ausente |
SOURCE_UNREADABLE | el archivo del locale de origen no existe |
SOURCE_INVALID | el archivo del locale de origen no se pudo leer o parsear; envuelve el error de lectura del adaptador |
LOCK_FILE_INVALID | el archivo de bloqueo está presente pero corrupto, sobredimensionado o en una versión no admitida |
LOCK_CONTENDED | el bloqueo de escritura de un locale no se pudo adquirir antes de su tiempo límite; el mensaje nombra la ruta del archivo de bloqueo |
CONCURRENCY_INVALID | se definió concurrency pero no es un entero de al menos 1; se lanza antes de que corra ningún locale |
CONCURRENCY_BUDGET_CONFLICT | una ejecución real fijó concurrency por encima de 1 con maxTokens configurado; se lanza antes de cualquier llamada al proveedor (un dry-run queda exento) |
LOCALE_FAILED | nunca se lanza: el code de reserva registrado en el error de un locale fallido |
Dos excepciones a la regla de una sola clase de error: retranslateEntry relanza el ProviderError
propio del proveedor cuando la llamada única falla, y runStatus no lanza nunca. Para cómo estos
códigos se corresponden con los códigos de salida de la CLI, consulta
CI y códigos de salida; para ayuda a partir del síntoma, consulta
Solución de problemas.