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

Esta página fue traducida automáticamente, así que puede contener errores o sonar un poco raro. La versión en inglés es la fuente de la verdad. Lee el original en inglés.

@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/sdk

Requiere 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? }.

  • dryRun lee, compara e informa sin construir ni llamar al proveedor y sin escribir nada.
  • prune elimina del archivo escrito y del bloqueo las claves huérfanas (claves de destino ausentes del origen). generatePlurals sintetiza 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.
  • concurrency traduce hasta ese número de locales de destino a la vez (por defecto 1, estrictamente en serie). Un valor menor que 1 lanza CONCURRENCY_INVALID; en una ejecución real, un valor mayor que 1 con maxTokens configurado lanza CONCURRENCY_BUDGET_CONFLICT (un dry-run queda exento).
  • cache está 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-cache de la CLI).
  • onProgress se llama a medida que avanza la ejecución (por inicio y fin de cada locale, y por sub-lote del proveedor), y onLockWait se 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. lockAcquireTimeoutMs anula cuánto tiempo reintenta un bloqueo de escritura en disputa antes de fallar con LOCK_CONTENDED.
  • maxBatchSize, maxTokens y budgetBehavior son 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_REORDERED y PROVIDER_DEGRADED. Una señal de revisión es consultiva y nunca retiene una clave, así que una clave nunca aparece a la vez en needsReview y en integrityMismatches. 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_RETAINED y BUDGET_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.usage es la suma sobre los locales.
  • budget aparece solo cuando maxTokens está configurado: { maxTokens, behavior, supported, tokensUsed, exceeded }. Frente a un proveedor sin tokens o una ejecución en seco sigue presente con supported: 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_FAILED solo 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 de translate los deja vacíos): una fila changed en 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ódigoCuándo
CONFIG_NOT_FOUNDla búsqueda no encontró ninguna configuración, o un configPath explícito no existe (lanzado por loadConfig)
CONFIG_INVALIDse encontró una configuración pero no se puede parsear o falla la validación, o su archivo de glosario no se pudo resolver
UNKNOWN_FORMATno hay adaptador registrado para el formato configurado; se lanza antes de leer ningún archivo
UNKNOWN_LOCALEun locale solicitado no está entre los locales de destino configurados
UNKNOWN_KEYuna clave solicitada no está en el recurso de origen (keyValue, editEntry, retranslateEntry)
PROVIDER_CONSTRUCTION_FAILEDel proveedor no se pudo construir; envuelve el error propio del proveedor, incluida una clave API ausente
SOURCE_UNREADABLEel archivo del locale de origen no existe
SOURCE_INVALIDel archivo del locale de origen no se pudo leer o parsear; envuelve el error de lectura del adaptador
LOCK_FILE_INVALIDel archivo de bloqueo está presente pero corrupto, sobredimensionado o en una versión no admitida
LOCK_CONTENDEDel 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_INVALIDse definió concurrency pero no es un entero de al menos 1; se lanza antes de que corra ningún locale
CONCURRENCY_BUDGET_CONFLICTuna 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_FAILEDnunca 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.

Edit on GitHub